Dubbo 簡介
什么是 Dubbo
Apache Dubbo (incubating) |?d?b??| 是一款高性能笨奠、輕量級的開源 Java RPC 分布式服務框架日矫,它提供了三大核心能力:面向接口的遠程方法調(diào)用,智能容錯和負載均衡懈贺,以及服務自動注冊和發(fā)現(xiàn)。她最大的特點是按照分層的方式來架構(gòu)坡垫,使用這種方式可以使各個層之間解耦合(或者最大限度地松耦合)。從服務模型的角度來看画侣,Dubbo 采用的是一種非常簡單的模型冰悠,要么是提供方提供服務,要么是消費方消費服務配乱,所以基于這一點可以抽象出服務提供方(Provider)和服務消費方(Consumer)兩個角色溉卓。
備注: 2019 年 5 月 21 日 Apache 軟件基金會發(fā)表博文,宣布 Dubbo 在 2019 年 5 月 20 日 這天正式畢業(yè)搬泥,成為 Apache 的頂級項目桑寨。
Dubbo 架構(gòu)
[圖片上傳失敗...(image-3b2a67-1563198682515)]
節(jié)點角色說明
節(jié)點 | 角色說明 |
---|---|
Provider | 暴露服務的服務提供方 |
Consumer | 調(diào)用遠程服務的服務消費方 |
Registry | 服務注冊與發(fā)現(xiàn)的注冊中心 |
Monitor | 統(tǒng)計服務的調(diào)用次數(shù)和調(diào)用時間的監(jiān)控中心 |
Container | 服務運行容器 |
調(diào)用關(guān)系說明
- 服務容器負責啟動,加載忿檩,運行服務提供者
- 服務提供者在啟動時尉尾,向注冊中心注冊自己提供的服務
- 服務消費者在啟動時,向注冊中心訂閱自己所需的服務
- 注冊中心返回服務提供者地址列表給消費者燥透,如果有變更沙咏,注冊中心將基于長連接推送變更數(shù)據(jù)給消費者
- 服務消費者,從提供者地址列表中班套,基于軟負載均衡算法肢藐,選一臺提供者進行調(diào)用,如果調(diào)用失敗吱韭,再選另一臺調(diào)用
- 服務消費者和提供者吆豹,在內(nèi)存中累計調(diào)用次數(shù)和調(diào)用時間,定時每分鐘發(fā)送一次統(tǒng)計數(shù)據(jù)到監(jiān)控中心
Dubbo 功能特點
- 面向接口代理的高性能 RPC 調(diào)用: 提供高性能的基于代理的遠程調(diào)用能力,服務以接口為粒度痘煤,為開發(fā)者屏蔽遠程調(diào)用底層細節(jié)
- 智能負載均衡: 內(nèi)置多種負載均衡策略凑阶,智能感知下游節(jié)點健康狀況,顯著減少調(diào)用延遲速勇,提高系統(tǒng)吞吐量
- 服務自動注冊與發(fā)現(xiàn): 支持多種注冊中心服務晌砾,服務實例上下線實時感知
- 高度可擴展能力: 遵循微內(nèi)核 + 插件的設計原則,所有核心能力如 Protocol烦磁、Transport养匈、Serialization 被設計為擴展點,平等對待內(nèi)置實現(xiàn)和第三方實現(xiàn)
- 運行期流量調(diào)度: 內(nèi)置條件都伪、腳本等路由策略呕乎,通過配置不同的路由規(guī)則,輕松實現(xiàn)灰度發(fā)布陨晶,同機房優(yōu)先等功能
- 可視化的服務治理與運維: 提供豐富服務治理猬仁、運維工具:隨時查詢服務元數(shù)據(jù)、服務健康狀態(tài)及調(diào)用統(tǒng)計先誉,實時下發(fā)路由策略湿刽、調(diào)整配置參數(shù)
附:擴展閱讀
什么是 RPC
分布式是促使 RPC 誕生的領域,RPC 是一種編程模型褐耳,并沒有規(guī)定你具體要怎樣實現(xiàn),無論使用 HTTP 或是 RMI 都是可以的雅镊。
假設你有一個計算器接口,Calculator仁烹,以及它的實現(xiàn)類 CalculatorImpl咧虎,那么在系統(tǒng)還是 單體應用 時,你要調(diào)用 Calculator 的 add 方法來執(zhí)行一個加運算僚饭,直接 new 一個 CalculatorImpl胧砰,然后調(diào)用 add 方法就行了,這其實就是非常普通的 本地函數(shù)調(diào)用偿乖,因為在 同一個地址空間,或者說在同一塊內(nèi)存贪薪,所以通過方法棧和參數(shù)棧就可以實現(xiàn)。
[圖片上傳失敗...(image-319fc1-1563198682515)]
現(xiàn)在画切,基于高性能和高可靠等因素的考慮,你決定將系統(tǒng)改造為分布式應用霍弹,將很多可以共享的功能都單獨拎出來,比如上面說到的計算器岛宦,你單獨把它放到一個服務里頭耍缴,讓別的服務去調(diào)用它砾肺。
[圖片上傳失敗...(image-3fdd96-1563198682515)]
這下問題來了变汪,服務 A 里頭并沒有 CalculatorImpl 這個類蚁趁,那它要怎樣調(diào)用服務 B 的 CalculatorImpl 的 add 方法呢?
RPC 要解決的兩個問題
- 解決分布式系統(tǒng)中,服務之間的調(diào)用問題
- 遠程調(diào)用時童芹,要能夠像本地調(diào)用一樣方便,讓調(diào)用者感知不到遠程調(diào)用的邏輯
如何實現(xiàn)一個 RPC
實際情況下署咽,RPC 很少用到 HTTP 協(xié)議來進行數(shù)據(jù)傳輸宁否,畢竟我只是想傳輸一下數(shù)據(jù)而已缀遍,何必動用到一個文本傳輸?shù)膽脤訁f(xié)議呢,我為什么不直接使用二進制傳輸域醇?比如直接用 Java 的 Socket 協(xié)議進行傳輸?
不管你用何種協(xié)議進行數(shù)據(jù)傳輸锅铅,一個完整的 RPC 過程,都可以用下面這張圖來描述
[圖片上傳失敗...(image-509b1e-1563198682515)]
以左邊的 Client 端為例盐须,Application 就是 RPC 的調(diào)用方贼邓,Client Stub 就是我們上面說到的代理對象,也就是那個看起來像是 Calculator 的實現(xiàn)類眼溶,其實內(nèi)部是通過 RPC 方式來進行遠程調(diào)用的代理對象晓勇,至于 Client Run-time Library,則是實現(xiàn)遠程調(diào)用的工具包绰筛,比如 JDK 的 Socket描融,最后通過底層網(wǎng)絡實現(xiàn)實現(xiàn)數(shù)據(jù)的傳輸。
這個過程中最重要的就是 序列化 和 反序列化 了骏庸,因為數(shù)據(jù)傳輸?shù)臄?shù)據(jù)包必須是二進制的年叮,你直接丟一個 Java 對象過去,人家可不認識一姿,你必須把 Java 對象序列化為二進制格式叮叹,傳給 Server 端爆存,Server 端接收到之后,再反序列化為 Java 對象先较。
RPC vs Restful
RPC 是面向過程,Restful 是面向資源噪叙,并且使用了 HTTP 動詞。從這個維度上看苞笨,Restful 風格的 URL 在表述的精簡性子眶、可讀性上都要更好。
阿里為何放棄 Zookeeper
CAP
有個思考粤咪,從 CAP 角度考慮寥枝,服務注冊中心是 CP 系統(tǒng)還是 AP 系統(tǒng)呢磁奖?
- 服務注冊中心是為了服務間調(diào)用服務的比搭,那么絕對不允許因為服務注冊中心出現(xiàn)了問題而導致服務間的調(diào)用出問題
- 假如有 node1,node2身诺,node3 集群節(jié)點霉赡。保存著可用服務列表 ip1,ip2同廉,ip3迫肖,試想如果此時不一致蟆湖,比如 node1 只保存了ip1,ip2隅津,此時服務讀取 node1 的節(jié)點,那么會造成什么影響伦仍?
調(diào)用 node1 的服務,頂多就是負載均衡時不會有流量打到 ip3隧枫,然后等 node1 同步回 ip3 后谓苟,又一致了涝焙,這對服務其實沒什么太大影響。所以赤兴,推測出服務注冊中心應該是個 AP 系統(tǒng)派草。
Zookeeper 是個 CP 系統(tǒng),強一致性
- 場景1艺普,當 master 掛了歧譬,此時 Zookeeper 集群需要重新選舉搏存,而此時服務需要來讀取可用服務,是不可用的缩焦。影響到了服務的可用性當然你可以說服務本地有緩存可用列表袁滥。然而下面這種方式就更無法處理了灾螃。
- 場景2,分區(qū)可用嵌赠。試想,有 3 個機房齿税,如果其中機房 3 和機房 1偎窘,2 網(wǎng)絡斷了,那么機房 3 的注冊中心就不能注冊新的機器了陌知,這顯然也不合理從健康檢查角度來看
[圖片上傳失敗...(image-abf53f-1563198682515)]
Zookeeper 是通過 TCP 的心跳判斷服務是否可用仆葡,但 TCP 的活性并不代表服務是可用的志笼,如:連接池已滿纫溃,DB 掛了等
理想的注冊中心
- 服務自動注冊發(fā)現(xiàn)。最好有新的服務注冊上去時還能推送到調(diào)用端
- 能對注冊上來的機器方便的進行管理紊浩,能手動刪除(發(fā)送信號讓服務優(yōu)雅下線)、恢復機器
- 服務的健康檢查费彼,能真正的檢測到服務是否可用
- 可以看到是否有其他調(diào)用服務正在訂閱注冊上來的服務
- 能夠帶上些除了 IP 外的其它信息