調用關系說明
服務容器負責啟動,加載,運行服務提供者。
服務提供者在啟動時,向注冊中心注冊自己提供的服務。
服務消費者在啟動時,向注冊中心訂閱自己所需的服務。
注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基於長連接推送變更數據給消費者。
服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。
服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鍾發送一次統計數據到監控中心。
Dubbo 架構具有以下幾個特點,分別是連通性、健壯性、伸縮性、以及向未來架構的升級性。
連通性
注冊中心負責服務地址的注冊與查找,相當於目錄服務,服務提供者和消費者只在啟動時與注冊中心交互,注冊中心不轉發請求,壓力較小
監控中心負責統計各服務調用次數,調用時間等,統計先在內存匯總后每分鍾一次發送到監控中心服務器,並以報表展示
服務提供者向注冊中心注冊其提供的服務,並匯報調用時間到監控中心,此時間不包含網絡開銷
服務消費者向注冊中心獲取服務提供者地址列表,並根據負載算法直接調用提供者,同時匯報調用時間到監控中心,此時間包含網絡開銷
注冊中心,服務提供者,服務消費者三者之間均為長連接,監控中心除外
注冊中心通過長連接感知服務提供者的存在,服務提供者宕機,注冊中心將立即推送事件通知消費者
注冊中心和監控中心全部宕機,不影響已運行的提供者和消費者,消費者在本地緩存了提供者列表
注冊中心和監控中心都是可選的,服務消費者可以直連服務提供者
健狀性
監控中心宕掉不影響使用,只是丟失部分采樣數據
數據庫宕掉后,注冊中心仍能通過緩存提供服務列表查詢,但不能注冊新服務
注冊中心對等集群,任意一台宕掉后,將自動切換到另一台
注冊中心全部宕掉后,服務提供者和服務消費者仍能通過本地緩存通訊
服務提供者無狀態,任意一台宕掉后,不影響使用
服務提供者全部宕掉后,服務消費者應用將無法使用,並無限次重連等待服務提供者恢復
伸縮性
注冊中心為對等集群,可動態增加機器部署實例,所有客戶端將自動發現新的注冊中心
服務提供者無狀態,可動態增加機器部署實例,注冊中心將推送新的服務提供者信息給消費者
配置覆蓋關系
以 timeout 為例,顯示了配置的查找順序,其它 retries, loadbalance, actives 等類似:
法級優先,接口級次之,全局配置再次之。
如果級別一樣,則消費者優先,提供者次之。
作服務的提供者,比服務使用方更清楚服務性能參數建議由服務提供方設置超時,合理的重試次數,版本號,負載均衡策略,如果一個消費方同時引用多個服務,就不需要關心每個服務的超時設置。
在 Provider 配置后,Consumer 不配置則會使用Provider 的配置值,即 Provider 配置可以作為 Consumer 的缺省值 。否則,Consumer 會使用 Consumer 端的全局設置,這對於 Provider 不可控的,並且往往是不合理的Provider 上盡量多配置 Consumer 端的屬性,讓 Provider 實現者一開始就思考 Provider 服務特點、服務質量的問題。
配置覆蓋策略
jvm啟動參數 >>xml配置 >> properties配置
只有 XML 沒有配置時,dubbo.properties 的相應配置項才會生效,通常用於共享公共配置,如應用名。
集群容錯cluster
Failover Cluster
失敗自動切換,當出現失敗,重試其它服務器 。通常用於讀操作,但重試會帶來更長延遲。可通過 retries="2" 來設置重試次數(不含第一次
Failfast Cluster
快速失敗,只發起一次調用,失敗立即報錯。通常用於非冪等性的寫操作,如新增記錄。
Failsafe Cluster
失敗安全,出現異常時,直接忽略。通常用於寫入審計日志等操作。
Failback Cluster
失敗自動恢復,后台記錄失敗請求,定時重發。通常用於消息通知操作。
Forking Cluster
並行調用多個服務器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過forks="2" 來設置最大並行數。
Broadcast Cluster
廣播調用所有提供者,逐個調用,任意一台報錯則報錯 。通常用於通知所有提供者更新緩存或日志等本地資源信息。
負載均衡策略loadbalance
Random LoadBalance
隨機,按權重設置隨機概率。在一個截面上碰撞的概率高,但調用量越大分布越均勻,且按概率使用權重后也比較均勻,有利於動態調整提供者權重。
RoundRobin LoadBalance
輪循,按公約后的權重設置輪循比率。存在慢的提供者累積請求的問題,如:第一台機器很慢,但沒掛,當請求調到第一台時就卡在那,久而久之,所有請求都卡在調到第一台上。
LeastActive LoadBalance
最少活躍調用數,相同活躍數的隨機,活躍數指調用前后計數差。使慢的提供者收到更少請求,因為越慢的提供者的調用前后計數差會越⼤。
ConsistentHash LoadBalance
一致性 Hash,相同參數的請求總是發到同一提供者。當某一台提供者掛時,原本發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引起劇烈變動。算法參見 http://en.wikipedia.org/wiki/Consistent_hashing缺省只對第一個參數 Hash,如果要修改,請配置 <dubbo:parameter key="hash.arguments" value="0,1" />缺省用 160 份虛擬節點,如果要修改,請配置 <dubbo:parameter key="hash.nodes" value="320" />
一個應用可以只訂閱服務,或者只注冊服務
<dubbo:registry address="10.20.153.10:9090" register="false" />
<dubbo:registry id="qdRegistry" address="10.20.141.150:9090" subscribe="false" />
多協議
Dubbo 允許配置多協議,在不同服務上支持不同協議或者同一服務上同時支持多種協議,不同服務在性能上適用不同協議進行傳輸,如大數據量用短連接協議,小數據高並發用長連接協議
多注冊中心
Dubbo支持同一服務向多注冊中心同時注冊,或者不同服務分別注冊到不同的注冊中心上去,甚至可以同時引用注冊在不同注冊中心上的同名服務。另外,注冊中心是支持自定義擴展的 。
並發控制
限制 com.foo.BarService 的每個方法,服務器端並發執行(或占用線程池線程數)不能超過 10 個:
<dubbo:service interface="com.foo.BarService" executes="10" />
限制 com.foo.BarService 的每個方法,每個客戶端並發執行(或占用連接的請求數)不能超過 10 個:
<dubbo:service interface="com.foo.BarService" actives="10" />
連接控制
服務端連接控制 限制服務器端接受的連接不能超過 10 個 <dubbo:provider protocol="dubbo" accepts="10" />
客戶端連接控制 限制客戶端服務使用連接不能超過 10 個 <dubbo:reference interface="com.foo.BarService" connections="10" />
延遲連接 延遲連接用於減少長連接數。當有調用發起時,再創建長連接。
<dubbo:protocol name="dubbo" lazy="true" />注意:該配置只對使用長連接的 dubbo 協議生效
Dubbo 緩存文件
提供者列表緩存文件:<dubbo:registry file=”${user.home}/output/dubbo.cache” />
有多個應用進程注意不要使用同一個文件,避免內容被覆蓋
服務分組
當一個接口有多種實現時,可以用 group 區分
<dubbo:service group="feedback" interface="com.xxx.IndexService" /> <dubbo:service group="member" interface="com.xxx.IndexService" />
<dubbo:reference id="feedbackIndexService" group="feedback" interface="com.xxx.IndexService" />
多版本
當一個接⼝實現,出現不兼容升級時,可以用版本號過渡,版本號不同的服務相互間不引用。
可以按照以下的步驟進⾏版本遷移:
1. 在低壓力時間段,先升級一半提供者為新版本
2. 再將所有消費者升級為新版本
3. 然后將剩下的一半提供者升級為新版本
結果緩存
結果緩存 ,用於加速熱門數據的訪問速度,Dubbo 提供聲明式緩存,以減少用戶加緩存的工作量 。
緩存類型
lru 基於最近最少使用原則刪除多余緩存,保持最熱的數據被緩存。
threadlocal 當前線程緩存,如一個頁面渲染,用到很多 portal,每個 portal 都要去查用戶信息,通過線程緩存,可以減少這種多余訪問。
jcache 與 JSR107 集成,可以橋接各種緩存實現。
<dubbo:reference interface="com.foo.BarService" cache="lru" />
上下文信息
上下文中存放的是當前調用過程中所需的環境信息。所有配置信息都將轉換為 URL 的參數
本地調用
本地調用使用了 injvm 協議,是一個偽協議,它不開啟端口,不發起遠程調用,只在 JVM 內直接關聯,但執行 Dubbo的 Filter 鏈。服務暴露與服務引用都需要聲明 injvm="true"
<dubbo:protocol name="injvm" /> <dubbo:provider protocol="injvm" /> <dubbo:service protocol="injvm" />
<dubbo:consumer injvm="true" .../> <dubbo:provider injvm="true" .../>
2.2.0 開始,每個服務默認都會在本地暴露。在引用服務的時候,默認優先引用本地服務
延遲暴露
如果你的服務需要預熱時間,如初始化緩存,等待相關資源就位等,可以使用delay 進行延遲暴露。
延遲5秒 <dubbo:service delay="5000" />
spring初始化之后 <dubbo:service delay="-1" />
dubbo://
Dubbo 缺省協議采用單一長連接和 NIO 異步通訊,適合於小數據量高並發的服務調用,以及服務消費者機器數遠大於服務提供者機器數的情況。反之,Dubbo缺省協議不適合傳送大數據量的服務,如傳文件,傳視頻等,除非請求量很低。
缺省協議,基於 mina 1.1.7 和 hessian 3.2.1 的 tbremoting 交互。
連接個數:單連接
連接方式:長連接
傳輸協議:TCP
傳輸口式:NIO 異步傳輸
序列化:Hessian 二進制序列化
適用范圍:傳入傳出參數數據包較小(建議小於100K),消費者比提供者個數多,單一消費者無法壓滿提供者,
盡量不要用 dubbo 協議傳輸文件件或超大字符串。
適用場景:常規遠程服務方法調用
參數及返回值需實現 Serializable 接口
接口增加方法,對客戶端無影響,如果該方法不是客戶端需要的,客戶端不需要重新部署。輸入參數和結果集中增加屬性,對客戶端無影響,如果客戶端並不需要新屬性,不用重新部署。
輸入參數和結果集屬性名變化,對客戶端序列化無影響.但是如果客戶端不重新部署,不管輸入還是輸出,屬性名變化的屬性值是獲取不到的。
rmi://
RMI 協議采用 JDK 標准的 java.rmi.* 實現,采用阻塞式短連接和 JDK 標准序列化方式。
注意:如果正在使用 RMI 提供服務給外部訪問 ,同時應用中依賴了老的 common-collections 包 的情況下,存在反序列化安全風險 。
連接個數:多連接
連接方式:短連接
傳輸協議:TCP
傳輸方式:同步傳輸
序列化:Java 標准⼆進制序列化
適用范圍:傳入傳出參數數據包大小混合,消費者與提供者個數差不多,可傳文件。
適用場景:常規遠程服務方法調用,與原生RMI服務互操作
參數及返回值需實現 Serializable 接口
dubbo 配置中的超時時間對 RMI 無效,需使用 java 啟動參數設置: -Dsun.rmi.transport.tcp.responseTimeout=3000
hessian://
Hessian 協議用於集成 Hessian 的服務,Hessian 底層采用 Http 通訊,采用 Servlet 暴露服務,Dubbo 缺省內嵌
Jetty 作為服務器實現。
Dubbo 的 Hessian 協議可以和原生 Hessian 服務互操作,即:
提供者用 Dubbo 的 Hessian 協議暴露服務,消費者直接用標准 Hessian 接口調用
或者提供方用標准 Hessian 暴露服務,消費方用 Dubbo 的 Hessian 協議調用。
連接個數:多連接
連接方式:短連接
傳輸協議:HTTP
傳輸方式:同步傳輸
序列化:Hessian二進制序列化
適用范圍:傳入傳出參數數據包較大,提供者⽐消費者個數多,提供者壓力較大,可傳文件。
適用場景:頁面傳輸,文件傳輸,或與原生hessian服務互操作
參數及返回值需實現 Serializable 接口
http://
基於 HTTP 表單的遠程調用協議,采用 Spring 的 HttpInvoker 實現
連接個數:多連接
連接方式:短連接
傳輸協議:HTTP
傳輸方式:同步傳輸
序列化:表單序列化
適用范圍:傳入傳出參數數據包大小合,提供者比消費者個數多,可用瀏覽器查看,可用表單或URL傳入參數,暫不支持傳文件。
適用場景:需同時給應用程序和瀏覽器 JS 使用的服務。
參數及返回值需符合 Bean 規范
webservice://
基於 WebService 的遠程調⽤協議,
提供者用 Dubbo 的 WebService 協議暴露服務,消費者直接用標准 WebService 接口調用,或者提供者標准 WebService 暴露服務,消費者用 Dubbo 的 WebService 協議調用。
連接個數:多連接
連接方式:短連接
傳輸協議:HTTP
傳輸方式:同步傳輸
序列化:SOAP 文本序列化
適用場景:系統集成,跨語言調用
參數及返回值需實現 Serializable 接口 參數盡量使用基本類型和 POJO
thrift://
memcached://
redis://
Multicast 注冊中心
Multicast 注冊中心不需要啟動任何中心節點,只要廣播地址一樣,就可以互相發現。
1. 提供方啟動時廣播自己的地址
2. 消費方啟動時廣播訂閱請求
3. 提供方收到訂閱請求時,單播自己的地址給訂閱者,如果設置了 unicast=false ,則廣播給訂閱者
4. 消費方收到提供方地址時,連接該地址進行 RPC 調用。
組播受網絡結構限制,只適合小規模應用或開發階段使用。組播地址段: 224.0.0.0 - 239.255.255.255
為了減少廣播量,Dubbo 缺省使用單播發送提供者地址信息給消費者,如果一個機器上同時啟了多個消費者進程,消費者需聲明 unicast=false ,否則只會有一個消費者能收到消息
<dubbo:registry address="multicast://224.5.6.7:1234?unicast=false" />
zookeeper 注冊中心
Zookeeper 是 Apacahe Hadoop 的子項目,是一個樹型的目錄服務,支持變更推送,適合作為 Dubbo 服務的注冊中心,工業強度較高,可用於生產環境,並推薦使用。
流程說明:
服務提供者啟動時: 向 /dubbo/com.foo.BarService/providers 目錄下寫入自己的 URL 地址
服務消費者啟動時: 訂閱 /dubbo/com.foo.BarService/providers 目錄下的提供者 URL 地址。並向/dubbo/com.foo.BarService/consumers 目錄下寫入自己的 URL 地址
監控中心啟動時: 訂閱 /dubbo/com.foo.BarService 目錄下的所有提供者和消費者 URL 地址。
支持以下功能:
當提供者出現斷電等異常停機時,注冊中心能自動刪除提供者信息
當注冊中心重啟時,能自動恢復注冊數據,以及訂閱請求
當會話過期時,能自動恢復注冊數據,以及訂閱請求
當設置 <dubbo:registry check="false" /> 時,記錄失敗注冊和訂閱請求,后台定時重試
可通過 <dubbo:registry username="admin" password="1234" /> 設置 zookeeper 登錄信息
可通過 <dubbo:registry group="dubbo" /> 設置 zookeeper 的根節點,不設置將使無根樹
支持 * 號通配符 <dubbo:reference group="*" version="*" /> ,可訂閱服務的所有分組和所有版本的提供者
Redis 注冊中心
使用 Redis 的 Key/Map 結構存儲數據結構:
主 Key 為服務名和類型 Map 中的 Key 為 URL 地址 Map 中的 Value 為過期時間,用於判斷臟數據,臟數據由監控中心刪除
使用 Redis 的 Publish/Subscribe 事件通知數據變更:通過事件的值區分事件類型: register , unregister , subscribe , unsubscribe
普通消費者直接訂閱指定服務提供者的 Key,只會收到指定服務的 register , unregister 事件 監控中心通過 psubscribe 功能訂閱 /dubbo/* ,會收到所有服務的所有變更事件
調用過程:
1. 服務提供方啟動時,向 Key:/dubbo/com.foo.BarService/providers 下,添加當前提供者的地址
2. 並向 Channel:/dubbo/com.foo.BarService/providers 發送 register 事件
3. 服務消費方啟動時,從 Channel:/dubbo/com.foo.BarService/providers 訂閱 register 和 unregister 事件
4. 並向 Key:/dubbo/com.foo.BarService/providers 下,添加當前消費者的地址
5. 服務消費方收到 register 和 unregister 事件后,從 Key:/dubbo/com.foo.BarService/providers 下獲取提供者地址列表
6. 服務監控中方啟動時,從 Channel:/dubbo/* 訂閱 register 和 unregister ,以及 subscribe 和 unsubsribe 事件
7. 服務監控中方收到 register 和 unregister 事件后,從 Key:/dubbo/com.foo.BarService/providers 下獲取提供者地址列表
8. 服務監控中方收到 subscribe 和 unsubsribe 事件后,從 Key:/dubbo/com.foo.BarService/consumers 下獲取消費者地址列表
Simple 注冊中心 本身就是一個普通的Dubbo 服務,可以減少第三方依賴,使整體通訊方式一致