Dubbo是一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA治理方案。最大的特點是按照分層的方式來架構,使用這種方式可以使各個層之間解耦合(或者最大限度地鬆耦合)。
(1)遠程通訊: 提供對多種基於長連接的NIO框架抽象封裝,包括多種線程模型,序列化,以及「請求-響應」模式的信息交換方式。
(2) 軟負載均衡及容錯機制: 提供基於接口方法的透明遠程過程調用,包括多協議支持,以及軟負載均衡,失敗容錯,地址路由,動態配置等集羣支持。可在內網替代F5等硬件負載均衡器,降低成本,減少單點。
(3) 服務自動註冊與發現: 基於註冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。
(4)提供完善的管理控制檯dubbo-admin與簡單的控制中心dubbo-monitor。
(5)Dubbo提供了伸縮性很好的插件模型,很方便進行擴展(ExtensionLoader)。
(6) 支持多協議 。(dubbo、RMI、Hessian、http等)
Dubbo採用全Spring配置方式,透明化接入應用,對應用沒有任何API侵入, 只需用Spring加載Dubbo的配置即可,Dubbo基於Spring的Schema擴展進行加載。
Provider: 暴露服務的服務提供方。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務註冊與發現的註冊中心。
Monitor: 統計服務的調用次調和調用時間的監控中心。
Container: 服務運行容器。
(1)服務容器負責啓動,加載,運行服務提供者。
(4)註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
(5) 服務消費者從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
(6)服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
Dubbo是Alibaba開源的分佈式服務框架,按分層結構方式架構,以達到各層間鬆耦合。可抽象出服務提供方和服務消費方兩個角色。
(1)服務定義:服務是圍繞服務提供方和服務消費方的,服務提供方實現服務,而服務消費方調用服務。
(2)服務註冊:對於服務提供方,它需要發佈服務,而且由於應用系統的複雜性,服務的數量、類型也不斷膨脹;對於服務消費方,它最關心如何獲取到它所需要的服務,而面對複雜的應用系統,需要管理大量的服務調用。而且,對於服務提供方和服務消費方來說,他們還有可能兼具這兩種角色,即既需要提供服務,有需要消費服務。
通過將服務統一管理起來,可以有效地優化內部應用對服務發佈/使用的流程和管理。服務註冊中心可以通過特定協議來完成服務對外的統一。Dubbo提供的註冊中心有如下幾種類型可供選擇:Zookeeper、Redis、Multicast、Simple註冊中心。
(3)服務監控:無論是服務提供方,還是服務消費方,他們都需要對服務調用的實際狀態進行有效的監控,從而改進服務質量。
(4)遠程通信與信息交換:遠程通信需要指定通信雙方所約定的協議,在保證通信雙方理解協議語義的基礎上,還要保證高效、穩定的消息傳輸。Dubbo繼承了當前主流的網絡通信框架,主要包括如下幾個:Netty、Mina、Grizzly。
(5)服務調用:(1)服務提供方發佈服務到服務註冊中心;
(2)服務消費方從服務註冊中心訂閱服務;
(3)服務消費方調用已經註冊的可用服務
(6)註冊/註銷服務:服務的註冊與註銷,是對服務提供方角色而言。
(7)服務訂閱/取消:爲了滿足應用系統的需求,服務消費方的可能需要從服務註冊中心訂閱指定的有服務提供方發佈的服務,在得到通知可以使用服務時,就可以直接調用服務。反過來,如果不需要某一個服務了,可以取消該服務。
(8)協議支持:dubbo支持多種協議,如下所示:Dubbo、HTTP、Thrift、Redis、RMI。在通信過程中,不同的服務等級一般對應着不同的服務質量,那麼選擇合適的協議便是一件非常重要的事情。你可以根據你應用的創建來選擇。例如,使用RMI協議,一般會受到防火牆的限制,所以對於外部與內部進行通信的場景,就不要使用RMI協議,而是基於HTTP協議或者Hessian協議。
參考補充(源碼模塊概述):
dubbo-common 公共邏輯模塊,包括Util類和通用模型。
dubbo-remoting 遠程通訊模塊,相當於Dubbo協議的實現,如果RPC用RMI協議則不需要使用此包。
dubbo-rpc 遠程調用模塊,抽象各種協議,以及動態代理,只包含一對一的調用,不關心集羣的管理。
dubbo-cluster 集羣模塊,將多個服務提供方僞裝爲一個提供方,包括:負載均衡、容錯、路由等,集羣的地址列表可以是靜態配置的,也可以是由註冊中心下發。
dubbo-registry 註冊中心模塊,基於註冊中心下發地址的集羣方式,以及對各種註冊中心的抽象。
dubbo-monitor 監控模塊,統計服務調用次數,調用時間的,調用鏈跟蹤的服務。
dubbo-config 配置模塊,是Dubbo對外的API,用戶通過Config使用Dubbo,隱藏Dubbo所有細節。
dubbo-container 容器模塊,是一個Standalone的容器,以簡單的Main加載Spring啓動,因爲服務通常不需要Tomcat/JBoss等Web容器的特性,沒必要用Web容器去加載服務。
(1)服務提供者暴露服務配置 標籤:<dubbo:service>
version |
服務版本,建議使用兩位數字版本,如:1.0,通常在接口不兼容時版本號才需要升級 |
group |
服務分組,當一個接口有多個實現,可以用分組區分 |
delay |
延遲註冊服務時間(毫秒) ,設爲-1時,表示延遲到Spring容器初始化完成時暴露服務 |
timeout |
遠程服務調用超時時間(毫秒) |
retries |
遠程服務調用重試次數,不包括第一次調用,不需要重試請設爲0 |
(2)服務消費者引用服務配置 :<dubbo:reference>
version |
服務版本,與服務提供者的版本一致 |
group |
服務分組,當一個接口有多個實現,可以用分組區分,必需和服務提供方一致 |
timeout |
服務方法調用超時時間(毫秒) |
retries |
遠程服務調用重試次數,不包括第一次調用,不需要重試請設爲0 |
check |
啓動時檢查提供者是否存在,true報錯,false忽略 |
url |
點對點直連服務提供者地址,將繞過註冊中心 |
(1)Random LoadBalance(隨機):按權重設置隨機概率。在一個截面上碰撞的概率高,但調用量越大分佈越均勻,而且按概率使用權重後也比較均勻,有利於動態調整提供者權重。(權重可以在dubbo管控臺配置)
(2)RoundRobin LoadBalance(輪詢):按公約後的權重設置輪循比率。存在慢的提供者累積請求問題,比如:第二臺機器很慢,但沒掛,當請求調到第二臺時就卡在那,久而久之,所有請求都卡在調到第二臺上。
(3)LeastActive LoadBalance(最少活躍調用數):最少活躍調用數,相同活躍數的隨機,活躍數指調用前後計數差。使慢的提供者收到更少請求,因爲越慢的提供者的調用前後計數差會越大。
(4)ConsistentHash LoadBalance(一致性哈希):相同參數的請求總是發到同一提供者。當某一臺提供者掛時,原本發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引起劇烈變動。缺省只對第一個參數Hash,如果要修改,請配置。
通過Token令牌防止用戶繞過註冊中心直連,然後在註冊中心上管理授權。Dubbo還提供服務黑白名單,來控制服務所允許的調用方。
(1)Failover Cluster(默認):失敗自動切換,當出現失敗,重試其它服務器。(缺省)通常用於讀操作,但重試會帶來更長延遲。可通過retries="2"來設置重試次數(不含第一次)。
<dubbo:service retries="2" cluster="failover"/>
(2)Failfast Cluster:快速失敗,只發起一次調用,失敗立即報錯。通常用於非冪等性的寫操作,比如新增記錄。
<dubbo:reference cluster="failfast" />
(3)Failsafe Cluster:失敗安全,出現異常時,直接忽略。通常用於寫入審計日誌等操作。
(4)Failback Cluster:失敗自動恢復,後臺記錄失敗請求,定時重發。通常用於消息通知操作。
(5)Forking Cluster:並行調用多個服務器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過forks="2"來設置最大並行數。
<dubbo:service cluster=「forking" forks="2"/>
因dubbo協議採用單一長連接,如果每次請求的數據包大小爲500KByte,假設網絡爲千兆網卡(1024Mbit=128MByte),每條連接最大7MByte(不同的環境可能不一樣,供參考),單個服務提供者的TPS(每秒處理事務數)最大爲:128MByte / 500KByte = 262。單個消費者調用單個服務提供者的TPS(每秒處理事務數)最大爲:7MByte / 500KByte = 14。如果能接受,可以考慮使用,否則網絡將成爲瓶頸。
因爲服務的現狀大都是服務提供者少,通常只有幾臺機器,而服務的消費者多,可能整個網站都在訪問該服務,比如Morgan的提供者只有6臺提供者,卻有上百臺消費者,每天有1.5億次調用,如果採用常規的hessian服務,服務提供者很容易就被壓跨,通過單一連接,保證單一消費者不會壓死提供者,長連接,減少連接握手驗證等,並使用異步IO,複用線程池,防止C10K問題。
(1)Dubbo協議:適用範圍:傳入傳出參數數據包較小(建議小於100K),消費者比提供者個數多,單一消費者無法壓滿提供者,儘量不要用dubbo協議傳輸大文件或超大字符串。適用場景:常規遠程服務方法調用。
(2)RMI協議:RMI協議採用JDK標準的java.rmi.*實現,採用阻塞式短連接和JDK標準序列化方式,Java標準的遠程調用協議。適用範圍:傳入傳出參數數據包大小混合,消費者與提供者個數差不多,可傳文件。適用場景:常規遠程服務方法調用,與原生RMI服務互操作。
(3)Hessian協議:Hessian協議用於集成Hessian的服務,Hessian底層採用Http通訊,採用Servlet暴露服務,Dubbo缺省內嵌Jetty作爲服務器實現。適用範圍:傳入傳出參數數據包較大,提供者比消費者個數多,提供者壓力較大,可傳文件。適用場景:頁面傳輸,文件傳輸,或與原生hessian服務互操作
(4)http協議:採用Spring的HttpInvoker實現,基於http表單的遠程調用協議。序列化:表單序列化(JSON)適用範圍:傳入傳出參數數據包大小混合,提供者比消費者個數多,可用瀏覽器查看,可用表單或URL傳入參數,暫不支持傳文件。適用場景:需同時給應用程序和瀏覽器JS使用的服務。
(5)Webservice:序列化:SOAP文本序列化;適用場景:系統集成,跨語言調用。
(6)Thrif:Thrift是Facebook捐給Apache的一個RPC框架,當前 dubbo 支持的 thrift 協議是對 thrift 原生協議的擴展,在原生協議的基礎上添加了一些額外的頭信息,比如service name,magic number等
(1)http://bbs.itheima.com/forum.php?mod=viewthread&tid=386556(附錄)
(2)http://shiyanjun.cn/archives/325.html(架構設計,核心要點)