Dubbo對Spring Cloud說:來老弟,我要擁抱你
- 2020 年 5 月 18 日
- 筆記
- Spring Cloud
項目地址
//github.com/yinjihuan/kitty-cloud
前言
Kitty Cloud 開源後有以為朋友在 GitHub 上給我提了一個 issues,問為什麼項目中要同時集成 Feign 和 Dubbo 兩個框架來調用服務。今天就來聊一聊這個問題,然後講下在 Kitty Cloud 中如何切換使用兩種調用方式。
為什麼要支持兩種協議?
關於支持兩種協議,我這個是一個開源項目,主要還是為了讓使用者有更多的選擇。當然框架本身不是我開發的,我只是使用者而已。
一種協議更統一化,兩種協議混着用也不是不可以,具體還是看實際需求。比如你們內部有個 ID 分發的服務,調用量很高,就是對性能有這極致的要求。那麼這個場景你就可以用 Rpc 來代替 Http 了。其他的正常使用 Http 協議就行,特殊場景的就用 Rpc 協議,互補而已。
用 Http 最好的點在於簡單,傳輸內容就是文本,調試什麼的都很方便。比如我要單獨測試某個服務的接口,直接 PostMan 上調用這個 Http 接口就可以了,或者用 Swagger。
如果是 Dubbo 的 Rpc, 我可能需要用 telnet 來調用。
還有就是網關層的轉發,如果是 Http 協議,直接轉發過去了。如果是 Rpc 協議,網關內部需要轉特殊處理,當然目前也有支持 Rpc 的網關。如果我們是兩種協議,網關這邊還是直接 Http 轉發過去即可,內部服務之前想用什麼協議讓使用者自己決定。
其實在 Spring Cloud 慢慢進入企業後,有很多人都會遇到一個問題就是老的服務都是用 Dubbo 來通信的,如果轉 Spring Cloud 技術棧,那麼勢必要去掉 Dubbo。
如果規模不大直接重構掉也沒關係,但是對於大規模的應用,服務數量眾多。不太可能一口吃成個胖子。就算要重構那也是一個一個的方式來,也就意味着在沒重構完之前,老的服務還是 Dubbo,但有一些服務已經變成 Spring Cloud 體系了。這個時候兼容就是一個迫切需要解決的問題。
Spring Cloud Alibaba 的出現就為這個問題提供了完美的解決方案,同時支持兩種協議,可以慢慢過渡遷移。
舉例說明
下面通過一個例子來說明:
下圖中有兩個服務,最開始都是 Rpc 協議,服務 A 通過 Rpc 方式調用服務 B。
當我們將服務 B 重構成 Http 協議後,服務 A 就需要使用 Http 方式來調用服務 B。
改造方案一
如果從實現需求上來講,很簡單,將服務 A 中調用的代碼給出用 Feign 或者 RestTemplate 調用即可。但是這樣也就意味着我重構了 B 服務,還需要改動 A 服務的代碼,很有可能不止 A 一個服務在調用 B 服務,也許有幾十個,那麼我是不是得改幾十個服務的調用方式。
顯然這個方案不可行。你如果這樣出方案,你老大一個眼神送給你,自己體會吧。。。。。
改造方案二
方案一既然被否了,那需求很明顯嘛,就是你可以重構成 Spring Cloud 技術棧,但是你不能影響使用方。
要想不影響使用方,感覺只能從 Dubbo 的調用這塊入手。也就是在Dubbo 底層去擴展,如果目標服務是老的 Rpc 協議,那麼調用方式保持不變即可。
如果目標服務變成新的 Http 協議,那麼就需要使用新的方式去調用,只有在底層兼容了才不會影響使用方。
改造方案三
第三種方案也就是我們現在目前的方案,讓服務 B 支持雙協議,支持雙協議後,那麼所有的調用方都不用改變,因為 Rpc 的方式還支持。如果有新的服務可以使用 Http 來調用 B 服務的接口。
怎麼支持兩種協議?
支持兩種協議的核心在於 Dubbo Spring Cloud ,Dubbo Spring Cloud 作為 Spring Cloud Alibaba 中的最核心組件,基本上適配了 Spring Cloud 技術棧。
接口還是單獨抽出來放在 API 模塊中,FeignClient 相關定義在接口上。
在實現類中同時暴露兩種協議,加上 Dubbo 的@Service 和@RestController 註解。
使用方只需要注入接口即可調用,如果想使用 Feign 調用就用@Autowired 進行注入。
@Autowired
private UserRemoteService userRemoteService;
如果想使用 Dubbo 進行調用就用@Reference 進行注入。
@Reference(version = DubboConstant.VERSION_V100, group = DubboConstant.DEFAULT_GROUP, check = false)
private UserRemoteService userRemoteService;
還有一個很重要的配置在於需要將 Dubbo 的註冊中心掛載到 Spring Cloud 註冊中心上。
dubbo.registry.address=spring-cloud://localhost
高級玩法
目前雖然支持了雙協議,但使用權交到了用戶手裡。就是你想用什麼協議發起調用都可以,是通過硬編碼的方式來處理的。
如果想靈活度更高的話,我們可以在 Dubbo 或者 Feign 的底層去擴展。比如基於 Feign 去擴展的話,那就是調用都是採用 Feign 的方式,不需要用@Reference 來注入客戶端。我們可以通過集成配置中心,用配置的方式來指定採用哪種協議調用。在 Feign 底層通過配置內容決定是否要走 Rpc 調用。如果要走 Rpc 可以用 Dubbo 的泛化調用。