1. 程式人生 > 實用技巧 >這可能是Dubbo比較全的知識整理

這可能是Dubbo比較全的知識整理

一、Dubbo的provider和consumer都配置timeout

在Provider上儘量多配置Consumer端屬性,原因如下:

  1. 作服務的提供者,比服務使用方更清楚服務效能引數,如呼叫的超時時間,合理的重試次數,等等

  2. 在Provider配置後,Consumer不配置則會使用Provider的配置值,即Provider配置可以作為Consumer的預設值。否則,Consumer會使用Consumer端的全域性設定,這對於Provider不可控的,並且往往是不合理的

  3. 配置的覆蓋規則:

    1. 方法級配置別優於介面級別,即小Scope優先

    2. Consumer端配置 優於 Provider配置 優於 全域性配置

二、Dubbo是怎麼嵌入spring容器的

dubbo通過BeanFactoryPostProcessor與BeanPostProcessor分別完成ServiceBean的註冊與被@Reference註釋的屬性的依賴注入,通過BeanPostProcessor完成配置檔案與相關配置類bean的屬性繫結。

@Service(dubbo的)註釋的bean會交由spring建立管理,同時註冊一個持有該bean的引用(beanName)ServiceBean。@Service配置的屬性最終會繫結到ServiceBean的屬性上,ServiceBean通過監聽spring事件完成服務的匯出(暴露)。

三、Dubbo服務掛了怎麼辦

  1. 註冊中心掛了,可以繼續通訊。消費者會將提供者的地址等資訊拉取到本地快取,所以註冊中心掛了可以繼續通訊。
  2. 一般都是叢集

四、Dubbo服務如何處理高併發請求

  1. Dubbo服務降級,dubbo監控中心配置(mock=force:return+null)
  2. Sentinel 輕量級流量控制產品,針對流量激增,系統負載過高等問題
  3. Apollo配置中心

五、dubbo超時重試、降級

  1. 如果是爭對消費端,那麼當消費端發起一次請求後,如果在規定時間內未得到服務端的響應則直接返回超時異常,但服務端的程式碼依然在執行。
  2. 如果是爭取服務端,那麼當消費端發起一次請求後,一直等待服務端的響應,服務端在方法執行到指定時間後如果未執行完,此時返回一個超時異常給到消費端。

服務超時設定:客戶端方法級>服務端方法級>客戶端介面級>服務端介面級>客戶端全域性>服務端全域性

服務超時實現原理:dubbo預設採用了netty做為網路元件,它屬於一種NIO的模式。消費端發起遠端請求後,執行緒不會阻塞等待服務端的返回,而是馬上得到一個ResponseFuture,消費端通過不斷的輪詢機制判斷結果是否有返回。因為是通過輪詢,輪詢有個需要特別注要的就是避免死迴圈,所以為了解決這個問題就引入了超時機制,只在一定時間範圍內做輪詢,如果超時時間就返回超時異常。

降級:呼叫coment service做服務降級,比如發生異常時返回一個mock的資料,dubbo預設支援mock。

五. 註冊中心宕機怎麼辦

假如zookeeper註冊中心宕掉,一段時間內服務消費方還是能夠呼叫提供方的服務的,實際上它使用的本地快取進行通訊,這只是dubbo健壯性的一種體現。

  1. 監控中心宕掉不影響使用,只是丟失部分取樣資料
  2. 資料庫宕掉後,註冊中心仍能通過快取提供服務列表查詢,但不能註冊新服務
  3. 註冊中心對等叢集,任意一臺宕掉後,將自動切換到另一臺
  4. 註冊中心全部宕掉後,服務提供者和服務消費者仍能通過本地快取通訊
  5. 服務提供者無狀態,任意一臺宕掉後,不影響使用
  6. 服務提供者全部宕掉後,服務消費者應用將無法使用,並無限次重連等待服務提供者恢復

六、Dubbo泛化呼叫

以下幾種場景可以考慮使用泛化呼叫:

  • 服務測試平臺
  • API 服務閘道器

泛化呼叫主要用於消費端沒有 API 介面的情況;不需要引入介面 jar 包,而是直接通過 GenericService 介面來發起服務呼叫,引數及返回值中的所有 POJO 均用 Map 表示。泛化呼叫對於服務端無需關注,按正常服務進行暴露即可。

七、Dubbo異常處理

某個系統呼叫dubbo請求,provider端(服務提供方)丟擲了自定義的業務異常,但consumer端(服務消費方)拿到的並不是自定義的業務異常。如果Dubbo的 provider端 丟擲異常(Throwable),則會被 provider端 的ExceptionFilter攔截到,執行以下invoke方法

如何正確的捕獲異常:

  1. 將該異常的包名以"java.或者"javax. " 開頭
  2. 使用受檢異常(繼承Exception)
  3. 不用異常,使用錯誤碼
  4. 把異常放到provider-api的jar包中
  5. 判斷異常message是否以XxxException.class.getName()開頭(其中XxxException是自定義的業務異常)
  6. provider實現GenericService介面
  7. provider的api明確寫明throws XxxException,釋出provider(其中XxxException是自定義的業務異常)
  8. 實現dubbo的filter,自定義provider的異常處理邏輯(方法可參考之前的文章給dubbo介面新增白名單——dubbo Filter的使用)

8. Dubbo 服務暴露

Dubbo 會在 Spring 例項化完 bean 之後,在重新整理容器最後一步釋出 ContextRefreshEvent 事件的時候,通知實現了 ApplicationListener 的 ServiceBean 類進行回撥 onApplicationEvent 事件方法,Dubbo 會在這個方法中呼叫 ServiceBean 父類 ServiceConfig 的 export 方法,而該方法真正實現了服務的(非同步或者非非同步)釋出。

9. Dubbo協議

dubbo:// rmi:// http:// hession:// redis://

10. Dubbo服務之間的呼叫是阻塞的嗎

Dubbo 預設協議採用單一長連線,底層實現是 Netty 的 NIO 非同步通訊機制;基於這種機制,Dubbo 實現了以下幾種呼叫方式:

  • 同步呼叫
  • 非同步呼叫
  • 引數回撥
  • 事件通知

11. Dubbo和SpringCloud區別

Dubbo 是 SOA 時代的產物,它的關注點主要在於服務的呼叫,流量分發、流量監控和熔斷。

而 Spring Cloud 誕生於微服務架構時代,考慮的是微服務治理的方方面面,另外由於依託了 Spring、Spring Boot 的優勢之上

兩個框架在開始目標就不一致,Dubbo 定位服務治理、Spring Cloud 是打造一個生態。

  • Dubbo 底層是使用 Netty 這樣的 NIO 框架,是基於 TCP 協議傳輸的,配合以 Hession 序列化完成 RPC 通訊。
  • Spring Cloud 是基於 Http 協議 Rest 介面呼叫遠端過程的通訊,相對來說 Http 請求會有更大的報文,佔的頻寬也會更多。但是 REST 相比 RPC 更為靈活,服務提供方和呼叫方的依賴只依靠一紙契約,不存在程式碼級別的強依賴,這在強調快速演化的微服務環境下,顯得更為合適,至於注重通訊速度還是方便靈活性,具體情況具體考慮。

12. Dubbo負載均衡

Random LoadBalance(預設,基於權重的隨機負載均衡機制)

RoundRobin LoadBalance(不推薦,基於權重的輪詢負載均衡機制)

LeastActive LoadBalance 最少活躍呼叫數

ConsistentHash LoadBalance 一致性 Hash

13. Dubbo 引數透傳

如果需要檢視一次呼叫的全鏈路日誌,則一般的做法是通過在系統邊界中產生一個 traceId,向呼叫鏈的後續服務傳遞 traceId,後續服務繼續使用 traceId 列印日誌,並再向其他後續服務傳遞 traceId,此過程簡稱,traceId透傳

  1. 基於RpcContext實現
  2. 基於Filter實現

14. Dubbo Filter

  1. 實現com.alibaba.dubbo.rpc.Filter介面:
  2. 配置檔案:在resources目錄下新增純文字檔案META-INF/dubbo/com.alibaba.dubbo.rpc.Filter
  3. 修改dubbo的provider配置檔案,在dubbo:provider中新增配置的filter

15. Dubbo的叢集容錯方案有哪些?

Dubbo 提供了多種容錯方案,預設為 failover 重試

Failsafe Cluster:失敗安全,出現異常時,直接忽略。通常用於寫入審計日誌等操作。
Failback Cluster:失敗自動恢復,後臺記錄失敗請求,定時重發。通常用於訊息通知操作。
Forking Cluster:並行呼叫多個伺服器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過 forks="2" 來設定最大並行數。
Broadcast Cluster:廣播呼叫所有提供者,逐個呼叫,任意一臺報錯則報錯 。通常用於通知所有提供者更新快取或日誌等本地資源資訊。

<dubbo:service retries="2" />