一、Dubbo的provider和consumer都配置timeout
在Provider上盡量多配置Consumer端屬性,原因如下:
作服務(wù)的提供者,比服務(wù)使用方更清楚服務(wù)性能參數(shù),如調(diào)用的超時(shí)時(shí)間,合理的重試次數(shù),等等
在Provider配置后,Consumer不配置則會(huì)使用Provider的配置值,即Provider配置可以作為Consumer的缺省值。否則,Consumer會(huì)使用Consumer端的全局設(shè)置,這對(duì)于Provider不可控的,并且往往是不合理的
-
配置的覆蓋規(guī)則:
方法級(jí)配置別優(yōu)于接口級(jí)別,即小Scope優(yōu)先
Consumer端配置 優(yōu)于 Provider配置 優(yōu)于 全局配置
二、Dubbo是怎么嵌入spring容器的
dubbo通過BeanFactoryPostProcessor與BeanPostProcessor分別完成ServiceBean的注冊(cè)與被@Reference注釋的屬性的依賴注入,通過BeanPostProcessor完成配置文件與相關(guān)配置類bean的屬性綁定。
@Service(dubbo的)注釋的bean會(huì)交由spring創(chuàng)建管理,同時(shí)注冊(cè)一個(gè)持有該bean的引用(beanName)ServiceBean。@Service配置的屬性最終會(huì)綁定到ServiceBean的屬性上,ServiceBean通過監(jiān)聽spring事件完成服務(wù)的導(dǎo)出(暴露)。
三、Dubbo服務(wù)掛了怎么辦
- 注冊(cè)中心掛了,可以繼續(xù)通信。消費(fèi)者會(huì)將提供者的地址等信息拉取到本地緩存,所以注冊(cè)中心掛了可以繼續(xù)通信。
- 一般都是集群
四、Dubbo服務(wù)如何處理高并發(fā)請(qǐng)求
- Dubbo服務(wù)降級(jí),dubbo監(jiān)控中心配置(mock=force:return+null)
- Sentinel 輕量級(jí)流量控制產(chǎn)品,針對(duì)流量激增,系統(tǒng)負(fù)載過高等問題
- Apollo配置中心
五、dubbo超時(shí)重試、降級(jí)
- 如果是爭(zhēng)對(duì)消費(fèi)端,那么當(dāng)消費(fèi)端發(fā)起一次請(qǐng)求后,如果在規(guī)定時(shí)間內(nèi)未得到服務(wù)端的響應(yīng)則直接返回超時(shí)異常,但服務(wù)端的代碼依然在執(zhí)行。
- 如果是爭(zhēng)取服務(wù)端,那么當(dāng)消費(fèi)端發(fā)起一次請(qǐng)求后,一直等待服務(wù)端的響應(yīng),服務(wù)端在方法執(zhí)行到指定時(shí)間后如果未執(zhí)行完,此時(shí)返回一個(gè)超時(shí)異常給到消費(fèi)端。
服務(wù)超時(shí)設(shè)置:客戶端方法級(jí)>服務(wù)端方法級(jí)>客戶端接口級(jí)>服務(wù)端接口級(jí)>客戶端全局>服務(wù)端全局
服務(wù)超時(shí)實(shí)現(xiàn)原理:dubbo默認(rèn)采用了netty做為網(wǎng)絡(luò)組件,它屬于一種NIO的模式。消費(fèi)端發(fā)起遠(yuǎn)程請(qǐng)求后,線程不會(huì)阻塞等待服務(wù)端的返回,而是馬上得到一個(gè)ResponseFuture,消費(fèi)端通過不斷的輪詢機(jī)制判斷結(jié)果是否有返回。因?yàn)槭峭ㄟ^輪詢,輪詢有個(gè)需要特別注要的就是避免死循環(huán),所以為了解決這個(gè)問題就引入了超時(shí)機(jī)制,只在一定時(shí)間范圍內(nèi)做輪詢,如果超時(shí)時(shí)間就返回超時(shí)異常。
降級(jí):調(diào)用coment service做服務(wù)降級(jí),比如發(fā)生異常時(shí)返回一個(gè)mock的數(shù)據(jù),dubbo默認(rèn)支持mock。
五. 注冊(cè)中心宕機(jī)怎么辦
假如zookeeper注冊(cè)中心宕掉,一段時(shí)間內(nèi)服務(wù)消費(fèi)方還是能夠調(diào)用提供方的服務(wù)的,實(shí)際上它使用的本地緩存進(jìn)行通訊,這只是dubbo健壯性的一種體現(xiàn)。
- 監(jiān)控中心宕掉不影響使用,只是丟失部分采樣數(shù)據(jù)
- 數(shù)據(jù)庫宕掉后,注冊(cè)中心仍能通過緩存提供服務(wù)列表查詢,但不能注冊(cè)新服務(wù)
- 注冊(cè)中心對(duì)等集群,任意一臺(tái)宕掉后,將自動(dòng)切換到另一臺(tái)
- 注冊(cè)中心全部宕掉后,服務(wù)提供者和服務(wù)消費(fèi)者仍能通過本地緩存通訊
- 服務(wù)提供者無狀態(tài),任意一臺(tái)宕掉后,不影響使用
- 服務(wù)提供者全部宕掉后,服務(wù)消費(fèi)者應(yīng)用將無法使用,并無限次重連等待服務(wù)提供者恢復(fù)
六、Dubbo泛化調(diào)用
以下幾種場(chǎng)景可以考慮使用泛化調(diào)用:
- 服務(wù)測(cè)試平臺(tái)
- API 服務(wù)網(wǎng)關(guān)
泛化調(diào)用主要用于消費(fèi)端沒有 API 接口的情況;不需要引入接口 jar 包,而是直接通過 GenericService 接口來發(fā)起服務(wù)調(diào)用,參數(shù)及返回值中的所有 POJO 均用 Map 表示。泛化調(diào)用對(duì)于服務(wù)端無需關(guān)注,按正常服務(wù)進(jìn)行暴露即可。
七、Dubbo異常處理
某個(gè)系統(tǒng)調(diào)用dubbo請(qǐng)求,provider端(服務(wù)提供方)拋出了自定義的業(yè)務(wù)異常,但consumer端(服務(wù)消費(fèi)方)拿到的并不是自定義的業(yè)務(wù)異常。如果Dubbo的 provider端 拋出異常(Throwable),則會(huì)被 provider端 的ExceptionFilter攔截到,執(zhí)行以下invoke方法
如何正確的捕獲異常:
- 將該異常的包名以"java.或者"javax. " 開頭
- 使用受檢異常(繼承Exception)
- 不用異常,使用錯(cuò)誤碼
- 把異常放到provider-api的jar包中
- 判斷異常message是否以XxxException.class.getName()開頭(其中XxxException是自定義的業(yè)務(wù)異常)
- provider實(shí)現(xiàn)GenericService接口
- provider的api明確寫明throws XxxException,發(fā)布provider(其中XxxException是自定義的業(yè)務(wù)異常)
- 實(shí)現(xiàn)dubbo的filter,自定義provider的異常處理邏輯(方法可參考之前的文章給dubbo接口添加白名單——dubbo Filter的使用)
8. Dubbo 服務(wù)暴露
Dubbo 會(huì)在 Spring 實(shí)例化完 bean 之后,在刷新容器最后一步發(fā)布 ContextRefreshEvent 事件的時(shí)候,通知實(shí)現(xiàn)了 ApplicationListener 的 ServiceBean 類進(jìn)行回調(diào) onApplicationEvent 事件方法,Dubbo 會(huì)在這個(gè)方法中調(diào)用 ServiceBean 父類 ServiceConfig 的 export 方法,而該方法真正實(shí)現(xiàn)了服務(wù)的(異步或者非異步)發(fā)布。
9. Dubbo協(xié)議
dubbo:// rmi:// http:// hession:// redis://
10. Dubbo服務(wù)之間的調(diào)用是阻塞的嗎
Dubbo 缺省協(xié)議采用單一長(zhǎng)連接,底層實(shí)現(xiàn)是 Netty 的 NIO 異步通訊機(jī)制;基于這種機(jī)制,Dubbo 實(shí)現(xiàn)了以下幾種調(diào)用方式:
- 同步調(diào)用
- 異步調(diào)用
- 參數(shù)回調(diào)
- 事件通知
11. Dubbo和SpringCloud區(qū)別
Dubbo 是 SOA 時(shí)代的產(chǎn)物,它的關(guān)注點(diǎn)主要在于服務(wù)的調(diào)用,流量分發(fā)、流量監(jiān)控和熔斷。
而 Spring Cloud 誕生于微服務(wù)架構(gòu)時(shí)代,考慮的是微服務(wù)治理的方方面面,另外由于依托了 Spring、Spring Boot 的優(yōu)勢(shì)之上
兩個(gè)框架在開始目標(biāo)就不一致,Dubbo 定位服務(wù)治理、Spring Cloud 是打造一個(gè)生態(tài)。
- Dubbo 底層是使用 Netty 這樣的 NIO 框架,是基于 TCP 協(xié)議傳輸?shù)?,配合?Hession 序列化完成 RPC 通信。
- Spring Cloud 是基于 Http 協(xié)議 Rest 接口調(diào)用遠(yuǎn)程過程的通信,相對(duì)來說 Http 請(qǐng)求會(huì)有更大的報(bào)文,占的帶寬也會(huì)更多。但是 REST 相比 RPC 更為靈活,服務(wù)提供方和調(diào)用方的依賴只依靠一紙契約,不存在代碼級(jí)別的強(qiáng)依賴,這在強(qiáng)調(diào)快速演化的微服務(wù)環(huán)境下,顯得更為合適,至于注重通信速度還是方便靈活性,具體情況具體考慮。
12. Dubbo負(fù)載均衡
Random LoadBalance(默認(rèn),基于權(quán)重的隨機(jī)負(fù)載均衡機(jī)制)
RoundRobin LoadBalance(不推薦,基于權(quán)重的輪詢負(fù)載均衡機(jī)制)
LeastActive LoadBalance 最少活躍調(diào)用數(shù)
ConsistentHash LoadBalance 一致性 Hash
13. Dubbo 參數(shù)透?jìng)?/h4>
如果需要查看一次調(diào)用的全鏈路日志,則一般的做法是通過在系統(tǒng)邊界中產(chǎn)生一個(gè) traceId,向調(diào)用鏈的后續(xù)服務(wù)傳遞 traceId,后續(xù)服務(wù)繼續(xù)使用 traceId 打印日志,并再向其他后續(xù)服務(wù)傳遞 traceId,此過程簡(jiǎn)稱,traceId透?jìng)?/strong>。
- 基于RpcContext實(shí)現(xiàn)
- 基于Filter實(shí)現(xiàn)
14. Dubbo Filter
- 實(shí)現(xiàn)com.alibaba.dubbo.rpc.Filter接口:
- 配置文件:在resources目錄下添加純文本文件META-INF/dubbo/com.alibaba.dubbo.rpc.Filter
- 修改dubbo的provider配置文件,在dubbo:provider中添加配置的filter
15. Dubbo的集群容錯(cuò)方案有哪些?
Dubbo 提供了多種容錯(cuò)方案,缺省為 failover 重試
Failsafe Cluster:失敗安全,出現(xiàn)異常時(shí),直接忽略。通常用于寫入審計(jì)日志等操作。
Failback Cluster:失敗自動(dòng)恢復(fù),后臺(tái)記錄失敗請(qǐng)求,定時(shí)重發(fā)。通常用于消息通知操作。
Forking Cluster:并行調(diào)用多個(gè)服務(wù)器,只要一個(gè)成功即返回。通常用于實(shí)時(shí)性要求較高的讀操作,但需要浪費(fèi)更多服務(wù)資源??赏ㄟ^ forks="2" 來設(shè)置最大并行數(shù)。
Broadcast Cluster:廣播調(diào)用所有提供者,逐個(gè)調(diào)用,任意一臺(tái)報(bào)錯(cuò)則報(bào)錯(cuò) 。通常用于通知所有提供者更新緩存或日志等本地資源信息。
<dubbo:service retries="2" />