對於Dubbo一些面試題自己的答案
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
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。通常用於通知所有提供者更新快取或日誌等本地資源資訊。