這可能是Dubbo比較全的知識整理
一、Dubbo的provider和consumer都配置timeout
在Provider上儘量多配置Consumer端屬性,原因如下:
-
作服務的提供者,比服務使用方更清楚服務效能引數,如呼叫的超時時間,合理的重試次數,等等
-
在Provider配置後,Consumer不配置則會使用Provider的配置值,即Provider配置可以作為Consumer的預設值。否則,Consumer會使用Consumer端的全域性設定,這對於Provider不可控的,並且往往是不合理的
-
配置的覆蓋規則:
-
方法級配置別優於介面級別,即小Scope優先
-
Consumer端配置 優於 Provider配置 優於 全域性配置
-
二、Dubbo是怎麼嵌入spring容器的
dubbo通過BeanFactoryPostProcessor與BeanPostProcessor分別完成ServiceBean的註冊與被@Reference註釋的屬性的依賴注入,通過BeanPostProcessor完成配置檔案與相關配置類bean的屬性繫結。
@Service(dubbo的)註釋的bean會交由spring建立管理,同時註冊一個持有該bean的引用(beanName)ServiceBean。@Service配置的屬性最終會繫結到ServiceBean的屬性上,ServiceBean通過監聽spring事件完成服務的匯出(暴露)。
三、Dubbo服務掛了怎麼辦
- 註冊中心掛了,可以繼續通訊。消費者會將提供者的地址等資訊拉取到本地快取,所以註冊中心掛了可以繼續通訊。
- 一般都是叢集
四、Dubbo服務如何處理高併發請求
- Dubbo服務降級,dubbo監控中心配置(mock=force:return+null)
- Sentinel 輕量級流量控制產品,針對流量激增,系統負載過高等問題
- Apollo配置中心
五、dubbo超時重試、降級
- 如果是爭對消費端,那麼當消費端發起一次請求後,如果在規定時間內未得到服務端的響應則直接返回超時異常,但服務端的程式碼依然在執行。
- 如果是爭取服務端,那麼當消費端發起一次請求後,一直等待服務端的響應,服務端在方法執行到指定時間後如果未執行完,此時返回一個超時異常給到消費端。
服務超時設定:客戶端方法級>服務端方法級>客戶端介面級>服務端介面級>客戶端全域性>服務端全域性
服務超時實現原理:dubbo預設採用了netty做為網路元件,它屬於一種NIO的模式。消費端發起遠端請求後,執行緒不會阻塞等待服務端的返回,而是馬上得到一個ResponseFuture,消費端通過不斷的輪詢機制判斷結果是否有返回。因為是通過輪詢,輪詢有個需要特別注要的就是避免死迴圈,所以為了解決這個問題就引入了超時機制,只在一定時間範圍內做輪詢,如果超時時間就返回超時異常。
降級:呼叫coment service做服務降級,比如發生異常時返回一個mock的資料,dubbo預設支援mock。
五. 註冊中心宕機怎麼辦
假如zookeeper註冊中心宕掉,一段時間內服務消費方還是能夠呼叫提供方的服務的,實際上它使用的本地快取進行通訊,這只是dubbo健壯性的一種體現。
- 監控中心宕掉不影響使用,只是丟失部分取樣資料
- 資料庫宕掉後,註冊中心仍能通過快取提供服務列表查詢,但不能註冊新服務
- 註冊中心對等叢集,任意一臺宕掉後,將自動切換到另一臺
- 註冊中心全部宕掉後,服務提供者和服務消費者仍能通過本地快取通訊
- 服務提供者無狀態,任意一臺宕掉後,不影響使用
- 服務提供者全部宕掉後,服務消費者應用將無法使用,並無限次重連等待服務提供者恢復
六、Dubbo泛化呼叫
以下幾種場景可以考慮使用泛化呼叫:
- 服務測試平臺
- API 服務閘道器
泛化呼叫主要用於消費端沒有 API 介面的情況;不需要引入介面 jar 包,而是直接通過 GenericService 介面來發起服務呼叫,引數及返回值中的所有 POJO 均用 Map
表示。泛化呼叫對於服務端無需關注,按正常服務進行暴露即可。
七、Dubbo異常處理
某個系統呼叫dubbo請求,provider端(服務提供方)丟擲了自定義的業務異常,但consumer端(服務消費方)拿到的並不是自定義的業務異常。如果Dubbo的 provider端 丟擲異常(Throwable),則會被 provider端 的ExceptionFilter攔截到,執行以下invoke方法
如何正確的捕獲異常:
- 將該異常的包名以"java.或者"javax. " 開頭
- 使用受檢異常(繼承Exception)
- 不用異常,使用錯誤碼
- 把異常放到provider-api的jar包中
- 判斷異常message是否以XxxException.class.getName()開頭(其中XxxException是自定義的業務異常)
- provider實現GenericService介面
- provider的api明確寫明throws XxxException,釋出provider(其中XxxException是自定義的業務異常)
- 實現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透傳。
- 基於RpcContext實現
- 基於Filter實現
14. Dubbo Filter
- 實現com.alibaba.dubbo.rpc.Filter介面:
- 配置檔案:在resources目錄下新增純文字檔案META-INF/dubbo/com.alibaba.dubbo.rpc.Filter
- 修改dubbo的provider配置檔案,在dubbo:provider中新增配置的filter
15. Dubbo的叢集容錯方案有哪些?
Dubbo 提供了多種容錯方案,預設為 failover 重試
Failsafe Cluster:失敗安全,出現異常時,直接忽略。通常用於寫入審計日誌等操作。
Failback Cluster:失敗自動恢復,後臺記錄失敗請求,定時重發。通常用於訊息通知操作。
Forking Cluster:並行呼叫多個伺服器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過 forks="2" 來設定最大並行數。
Broadcast Cluster:廣播呼叫所有提供者,逐個呼叫,任意一臺報錯則報錯 。通常用於通知所有提供者更新快取或日誌等本地資源資訊。
<dubbo:service retries="2" />