Dubbo 的設計思想,真優秀!
作者:叄滴水
博客:https://blog.csdn.net/qq_30285985/
本文來自作者「叄滴水」投稿,謝謝分享,也歡迎愛好技術分享的各位技術朋友向「Java 技術棧」投稿,讓更多人看到,投稿方式:關注公衆號「Java 技術棧」在後臺回覆:投稿。
起源
如果在一個項目中有兩個service
。userService
和orderService
。我們想要其中一個 service 調用另一個。
public class userService{
private orderService orderService;
public User getOrder(Long orderId){
return orderService.getOrder(orderId);
}
}
隨着業務的逐漸複雜,在開發中肯定會有業務拆分。初步是通過 maven 進行模塊的拆分。
不管 maven 如何拆分,都始終是在一個 jvm 中運行, 這樣只是在代碼開發時會清楚方便一點。但是,某一個service
在有較大壓力的情況下,沒有辦法單單對此service
做出調整。最終,我們是想要userService
和orderService
在不同的 jvm 中運行,如果orderService
訪問較多,我們可以只對它進行擴容。
如下圖,纔是我們最終想要的方案,對於這種方案,orderService
端,我們稱之爲服務提供者,調用orderService
的端,我們稱之爲服務消費者。這種思想,也爲 dubbo 的出現埋下了伏筆。
jvm 的 userService 如何調用 orderService 呢?
在 java 遠程調用多年的沉澱,一個接着一個框架的出現,在一點點的優化這個調用的過程。Java 核心技術教程和源碼已上傳:https://github.com/javastacks/javastack
首先是 socket 調用。在orderService
中開放 socket 服務,在userService
中進行遠程調用。
-
優點:解決了單機調用的問題。
-
缺點:代碼複雜,不易於擴展。
這可能是最初的一個遠程調用解決方案,筆者不曾遇到過純 socket 調用的框架。另外,Dubbo 系列面試題和答案全部整理好了,微信搜索 Java 技術棧,在後臺發送:面試,可以在線閱讀。
如何跨語言調用?
我們發現,在 java 的對象是不可以直接通過 socket 進行傳輸的,需要有一個序列化的過程。而且 java 的默認的序列化,是無法被其他語言解析的。這樣導致如果有其他語言提供的服務,是無法通過 java 調用。因此對於 socket 進行了升級,通過http+xml
進行信息的傳輸。這就出現了 webservice。
Web Service 技術, 能使得運行在不同機器上的不同應用無須藉助附加的、專門的第三方軟件或硬件, 就可相互交換數據或集成。依據 Web Service 規範實施的應用之間, 無論它們所使用的語言、 平臺或內部協議是什麼, 都可以相互交換數據。
Web Service 雖然早期很多人使用,但是到現在看來,這是一種過時的框架。因爲,同樣的一些數據,通過 json 會比 xml 少很多。通過 json 會更少的佔用帶寬。如下面數據。
{
"id": 12312,
"userName": "12312"
}
<id type="number">12312</id>
<userName type="string">12312</userName>
http 協議是應用層的一種協議,對於開放給外部系統時,是一個很好的選擇,它可以實現跨語言調用。如果是自己的 java 服務內部調用時,使用 http 協議,就有點浪費資源。
如上圖,http 協議在交互之前需要進行 tcp 三次握手,握手成功之後進行數據傳輸。一個 http 交互下來,有請求頭、請求體、響應頭、響應體。這些數據,在內部調用時,很多無關緊要的數據。也許可以自定義協議,簡化傳輸數據。這就出現了 dubbo 協議,一種內部調用的協議。
dubbo 協議追求的是數據量小,小則快,協議的設計也符合 dubbo 框框架的理念,適用與內部服務之間的數據交互。安全性就沒有 https 做的那麼好, 但是也不需要,畢竟 dubbo 協議設計的初衷就是內部使用的。
spring cloud 的 feign 組件內部使用 http 協議,內部調用可能有一些資源的浪費,但是 http 協議可以實現跨語言調用。
RPC 框架
對於一個 RPC 框架來說,只是能完成遠程調用,並不算完美。
一般開發一個服務需要多個機器進行部署,爲了防止出現單點故障。對於一個較爲完善的 RPC 框架來說,在多個機器提供同樣的一個服務的時候,需要自動做出選擇。好比上圖,userServuce
在調用orderService
的時候,需要自動識別集羣信息,並且自動選擇機器進行調用。
目前,orderService
只有一個服務,三臺機器,也許可以在userServuce
中配置三個 ip,然後自行編寫路由規則即可。但是隨着業務的複雜,機器的變化,也許,我們起初無法得知機器的 ip 信息。
爲了實現動態的機器添加與移除。最終,添加了一個機器的協調者,所有開放服務的機器在這個協調者中添加自己的開放服務的信息,這個協調者中會有哪些機器開放了哪些服務。這樣看來這個協調者類似一個 "通訊錄"。我們稱這個 "通訊錄" 爲註冊中心。
這樣一個較爲完善的 RPC 框架,就有了雛形。
-
服務提供者啓動之後向註冊中心,提交自己提供服務的信息。
-
服務消費者,在消費時,去註冊中心查詢是否有機器提供對應的服務。例如調用
orderService
時,可以發現有192.168.1.1
和192.168.1.2
機器有提供對應的服務。消費者可以根據隨機、輪訓等規則選擇調用哪個服務。 -
在有服務上線或者下線時,註冊中心可以對修改的信息進行通知。
這樣一套流程下來,就完美的實現的服務的動態部署,可以任意部署服務。
作爲協調者的註冊中心,佔據着一個重要地位。這樣來看,註冊中心主要實現了臨時數據存儲的功能。可以有多種選擇數據庫、redis、zookeeper、eureka、nacos、或者自己實現。
期初 dubbo 框架官方推薦使用 zookeeper 爲註冊中心,出現 nacos 之後,逐漸從 zookeeper 轉爲 nacos。
其中的原因有很多,有興趣的小夥伴可以微信搜索 Java 技術棧在歷史文章中搜索閱讀。
爲什麼 zookeeper 轉爲 nacos?結論爲:zookeeper 在大數據計算時做註冊中心是一個好的選擇,但是在服務調用時,也許數據不需要超強的一致性。nacos 是目前來說很友好的一個註冊中心,他提供了CP+AP
。還有可視化界面,還有配置中心等功能。功能相當完善。
springcloud 與 dubbo 的歷史
筆者不才,在 17 年時,這兩個詞才進入我的視線。當時還有一個超級火的 springboot。那個時候招聘,幾乎每個崗位都要求會 springboot。分享:Spring Boot 學習筆記。一時間,成爲了一個 java 開發的必備功底。
Spring Boot 基礎教程可以看這個,教程和源碼非常全:https://github.com/javastacks/spring-boot-best-practice
由於 springboot 在大大開發了開發的速度,而且 springcloud 的各個組件都比較完善,feign、網關、配置中心、熔斷等等。spring、springcloud 和 springboot 明顯是一家人。這讓一個孤身的 dubbo 有點不好立足,一些公司從 dubbo 框架轉爲 springcloud 全家桶。
2018 年 7 月份,eureka 停止更新。就目前來說 eureka 的功能單單作爲註冊中心,已經足夠優秀了。但是對於節奏如此快的互聯網時代,停止更新,就意味着會慢慢的消失。
2019 年 7 月 24 日晚,Spring Cloud 官方發佈公告 Spring Cloud Alibaba 即將畢業。提供了很多組件,對於大部分開發者而言,nacos、dubbo、seata
應該是較爲常用的組件。
-
nacos:註冊中心。
-
dubbo:一個基於 Java 的高性能開源 RPC 框架。
-
seata:一種高性能且易於使用的分佈式事務解決方案,可用於微服務架構。
nacos
是一個新推出的註冊中心,其中最亮眼的功能是提供了可視化界面,而且還附帶配置中心。瞬間 dubbo 就找到了家人。這些組件的出現讓 dubbo 又崛起了起來。而且 dubbo 本來擴展性就很好。可以進行協議擴展、調用攔截擴展、引用監聽擴展、集羣擴展等等。
另外 dubbo3.0 主力使用Triple
協議。完整兼容 gRPC over HTTP/2。推薦使用 protobuf
作爲默認序列化,在性能和跨語言上的效果都會更好。
結束語
就目前來看,dubbo 框架是一個目前位置非常優秀的 RPC 框架, 一個必須要學的一個框架。也許以後它會更加優秀,也許會落寞。但是其設計思想,非常值得開發者去學習。
最後,關注公衆號 Java 技術棧,在後臺回覆:面試,可以獲取我整理的 Java/ Dubbo 系列面試題和答案,非常齊全。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/JXd3NFNKOrLu7crEm4PWXw