Dubbo
頭幾天瞧到《Java頂尖口試必問-Dubbo口試題匯總》,對於內里得難點本人試着答復少許,有錯誤得請民眾指正。
Dubbo固然大概不革新了,可是背靠阿里得措施能力,中文報告得多樣,非常合適很多幾中小型分散式類型得開辟。
一、Dubbo通訊協議
第一、dubbo
Dubbo 缺省協議采用單一長連接和 NIO 異步通訊,適合於小數據量大並發的服務調用,以及服務消費者機器數遠大於服務提供者機器數的情況。
反之,Dubbo 缺省協議不適合傳送大數據量的服務,比如傳文件,傳視頻等,除非請求量很低。
- Transporter: mina, netty, grizzy
- Serialization: dubbo, hessian2, java, json
- Dispatcher: all, direct, message, execution, connection
- ThreadPool: fixed, cached
特性
缺省協議,使用基於 mina 1.1.7
和 hessian 3.2.1
的 tbremoting 交互。
- 連接個數:單連接
- 連接方式:長連接
- 傳輸協議:TCP
- 傳輸方式:NIO 異步傳輸
- 序列化:Hessian 二進制序列化
- 適用范圍:傳入傳出參數數據包較小(建議小於100K),消費者比提供者個數多,單一消費者無法壓滿提供者,盡量不要用 dubbo 協議傳輸大文件或超大字符串。
- 適用場景:常規遠程服務方法調用
第二、RMI
rmi://
RMI 協議采用 JDK 標准的 java.rmi.*
實現,采用阻塞式短連接和 JDK 標准序列化方式。
注意:如果正在使用 RMI 提供服務給外部訪問 1,同時應用里依賴了老的 common-collections 包 2 的情況下,存在反序列化安全風險 3。
特性
- 連接個數:多連接
- 連接方式:短連接
- 傳輸協議:TCP
- 傳輸方式:同步傳輸
- 序列化:Java 標准二進制序列化
- 適用范圍:傳入傳出參數數據包大小混合,消費者與提供者個數差不多,可傳文件。
- 適用場景:常規遠程服務方法調用,與原生RMI服務互操作
第三、hessian
Hessian 1 協議用於集成 Hessian 的服務,Hessian 底層采用 Http 通訊,采用 Servlet 暴露服務,Dubbo 缺省內嵌 Jetty 作為服務器實現。
Dubbo 的 Hessian 協議可以和原生 Hessian 服務互操作,即:
- 提供者用 Dubbo 的 Hessian 協議暴露服務,消費者直接用標准 Hessian 接口調用
- 或者提供方用標准 Hessian 暴露服務,消費方用 Dubbo 的 Hessian 協議調用。
特性
- 連接個數:多連接
- 連接方式:短連接
- 傳輸協議:HTTP
- 傳輸方式:同步傳輸
- 序列化:Hessian二進制序列化
- 適用范圍:傳入傳出參數數據包較大,提供者比消費者個數多,提供者壓力較大,可傳文件。
- 適用場景:頁面傳輸,文件傳輸,或與原生hessian服務互操作
第四、Http
基於 HTTP 表單的遠程調用協議,采用 Spring 的 HttpInvoker 實現 1
特性
- 連接個數:多連接
- 連接方式:短連接
- 傳輸協議:HTTP
- 傳輸方式:同步傳輸
- 序列化:表單序列化
- 適用范圍:傳入傳出參數數據包大小混合,提供者比消費者個數多,可用瀏覽器查看,可用表單或URL傳入參數,暫不支持傳文件。
- 適用場景:需同時給應用程序和瀏覽器 JS 使用的服務。
第五、WebService
基於 WebService 的遠程調用協議,基於 Apache CXF 1 的 frontend-simple
和 transports-http
實現 2。
可以和原生 WebService 服務互操作,即:
- 提供者用 Dubbo 的 WebService 協議暴露服務,消費者直接用標准 WebService 接口調用,
- 或者提供方用標准 WebService 暴露服務,消費方用 Dubbo 的 WebService 協議調用。
-
特性
- 連接個數:多連接
- 連接方式:短連接
- 傳輸協議:HTTP
- 傳輸方式:同步傳輸
- 序列化:SOAP 文本序列化
- 適用場景:系統集成,跨語言調用
第六、thrift
當前 dubbo 支持 1的 thrift 協議是對 thrift 原生協議 2 的擴展,在原生協議的基礎上添加了一些額外的頭信息,比如 service name,magic number 等。
使用 dubbo thrift 協議同樣需要使用 thrift 的 idl compiler 編譯生成相應的 java 代碼,后續版本中會在這方面做一些增強。
第七、緩存
memcached://
redis://
二、注冊中心
1)Multicast 注冊中心
Multicast 注冊中心不需要啟動任何中心節點,只要廣播地址一樣,就可以互相發現。
- 提供方啟動時廣播自己的地址
- 消費方啟動時廣播訂閱請求
- 提供方收到訂閱請求時,單播自己的地址給訂閱者,如果設置了
unicast=false
,則廣播給訂閱者 - 消費方收到提供方地址時,連接該地址進行 RPC 調用。
組播受網絡結構限制,只適合小規模應用或開發階段使用。組播地址段: 224.0.0.0 - 239.255.255.255
2)zookeeper 注冊中心
Zookeeper 是 Apacahe Hadoop 的子項目,是一個樹型的目錄服務,支持變更推送,適合作為 Dubbo 服務的注冊中心,工業強度較高,可用於生產環境,並推薦使用 1。
流程說明:
- 服務提供者啟動時: 向
/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="*" />
,可訂閱服務的所有分組和所有版本的提供者
3)Redis 注冊中心
使用 Redis 的 Key/Map 結構存儲數據結構:
- 主 Key 為服務名和類型
- Map 中的 Key 為 URL 地址
- Map 中的 Value 為過期時間,用於判斷臟數據,臟數據由監控中心刪除 3
使用 Redis 的 Publish/Subscribe 事件通知數據變更:
- 通過事件的值區分事件類型:
register
,unregister
,subscribe
,unsubscribe
- 普通消費者直接訂閱指定服務提供者的 Key,只會收到指定服務的
register
,unregister
事件 - 監控中心通過
psubscribe
功能訂閱/dubbo/*
,會收到所有服務的所有變更事件
調用過程:
- 服務提供方啟動時,向
Key:/dubbo/com.foo.BarService/providers
下,添加當前提供者的地址 - 並向
Channel:/dubbo/com.foo.BarService/providers
發送register
事件 - 服務消費方啟動時,從
Channel:/dubbo/com.foo.BarService/providers
訂閱register
和unregister
事件 - 並向
Key:/dubbo/com.foo.BarService/providers
下,添加當前消費者的地址 - 服務消費方收到
register
和unregister
事件后,從Key:/dubbo/com.foo.BarService/providers
下獲取提供者地址列表 - 服務監控中心啟動時,從
Channel:/dubbo/*
訂閱register
和unregister
,以及subscribe
和unsubsribe
事件 - 服務監控中心收到
register
和unregister
事件后,從Key:/dubbo/com.foo.BarService/providers
下獲取提供者地址列表 - 服務監控中心收到
subscribe
和unsubsribe
事件后,從Key:/dubbo/com.foo.BarService/consumers
下獲取消費者地址列表
4)Simple 注冊中心
Simple 注冊中心本身就是一個普通的 Dubbo 服務,可以減少第三方依賴,使整體通訊方式一致。
三、集群容錯
Failover Cluster
失敗自動切換,當出現失敗,重試其它服務器 1。通常用於讀操作,但重試會帶來更長延遲。可通過 retries="2"
來設置重試次數(不含第一次)。
重試次數配置如下:
<dubbo:service retries="2" />
或
<dubbo:reference retries="2" />
或
<dubbo:reference> <dubbo:method name="findFoo" retries="2" /> </dubbo:reference>
Failfast Cluster
快速失敗,只發起一次調用,失敗立即報錯。通常用於非冪等性的寫操作,比如新增記錄。
Failsafe Cluster
失敗安全,出現異常時,直接忽略。通常用於寫入審計日志等操作。
Failback Cluster
失敗自動恢復,后台記錄失敗請求,定時重發。通常用於消息通知操作。
Forking Cluster
並行調用多個服務器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過 forks="2"
來設置最大並行數。
Broadcast Cluster
廣播調用所有提供者,逐個調用,任意一台報錯則報錯 2。通常用於通知所有提供者更新緩存或日志等本地資源信息。