一文讲透Dubbo负载均衡之最小活跃数算法
本文是對(duì)于Dubbo負(fù)載均衡策略之一的最小活躍數(shù)算法的詳細(xì)分析。文中所示源碼,沒(méi)有特別標(biāo)注的地方均為2.6.0版本。
為什么沒(méi)有用截止目前的最新的版本號(hào)2.7.4.1呢?因?yàn)?.6.0這個(gè)版本里面有兩個(gè)bug。從bug講起來(lái),印象更加深刻。
最后會(huì)對(duì)2.6.0/2.6.5/2.7.4.1版本進(jìn)行對(duì)比,通過(guò)對(duì)比學(xué)習(xí),加深印象。
本文目錄
第一節(jié):Demo準(zhǔn)備。
本小節(jié)主要是為了演示方便,搭建了一個(gè)Demo服務(wù)。Demo中啟動(dòng)三個(gè)服務(wù)端,負(fù)載均衡策略均是最小活躍數(shù),權(quán)重各不相同。
第二節(jié):斷點(diǎn)打在哪?
本小節(jié)主要是分享我看源碼的方式。以及我們看源碼時(shí)斷點(diǎn)如何設(shè)置,怎么避免在源碼里面"瞎逛"。
第三節(jié):模擬環(huán)境。
本小節(jié)主要是基于Demo的改造,模擬真實(shí)環(huán)境。在此過(guò)程中發(fā)現(xiàn)了問(wèn)題,引申出下一小節(jié)。
第四節(jié):active為什么是0?
本小節(jié)主要介紹了RpcStatus類中的active字段在最小活躍數(shù)算法中所承擔(dān)的作用,以及其什么時(shí)候發(fā)生變化。讓讀者明白為什么需要在customer端配置ActiveLimitFilter攔截器。
第五節(jié):剖析源碼
本小節(jié)對(duì)于最小活躍數(shù)算法的實(shí)現(xiàn)類進(jìn)行了逐行代碼的解讀,基本上在每一行代碼上加入了注釋。屬于全文重點(diǎn)部分。
第六節(jié):Bug在哪里?
逐行解讀完源碼后,引出了2.6.0版本最小活躍數(shù)算法的兩個(gè)Bug。并通過(guò)2.6.0/2.6.5/2.7.4.1三個(gè)版本的異同點(diǎn)進(jìn)行交叉對(duì)比,加深讀者印象。
第七節(jié):意外收獲?
看官方文檔的時(shí)候發(fā)現(xiàn)了一處小小的筆誤,我對(duì)其進(jìn)行了修改并被merged。主要是介紹給開源項(xiàng)目貢獻(xiàn)代碼的流程。
PS:前一到三節(jié)主要是分享我看源碼的一點(diǎn)思路和技巧,如果你不感興趣可以直接從第四節(jié)開始看起。本文的重點(diǎn)是第四到第六節(jié)。
另:閱讀本文需要對(duì)Dubbo有一定的了解。
一.Demo準(zhǔn)備
我看源碼的習(xí)慣是先搞個(gè)Demo把調(diào)試環(huán)境搭起來(lái)。然后帶著疑問(wèn)去抽絲剝繭的Debug,不放過(guò)在這個(gè)過(guò)程中在腦海里面一閃而過(guò)的任何疑問(wèn)。
這篇文章分享的是Dubbo負(fù)載均衡策略之一最小活躍數(shù)(LeastActiveLoadBalance)。所以我先搭建一個(gè)Dubbo的項(xiàng)目,并啟動(dòng)三個(gè)provider供consumer調(diào)用。
三個(gè)provider的loadbalance均配置的是leastactive。權(quán)重分別是默認(rèn)權(quán)重、200、300。
默認(rèn)權(quán)重是多少?后面看源碼的時(shí)候,源碼會(huì)告訴你。
三個(gè)不同的服務(wù)提供者會(huì)給調(diào)用方返回自己是什么權(quán)重的服務(wù)。
啟動(dòng)三個(gè)實(shí)例。(注:上面的provider.xml和DemoServiceImpl其實(shí)只有一個(gè),每次啟動(dòng)的時(shí)候手動(dòng)修改端口、權(quán)重即可。)
到zookeeper上檢查一下,服務(wù)提供者是否正常:
可以看到三個(gè)服務(wù)提供者分別在20880、20881、20882端口。(每個(gè)紅框的最后5個(gè)數(shù)字就是端口號(hào))。
最后,我們?cè)倏捶?wù)消費(fèi)者。消費(fèi)者很簡(jiǎn)單,配置consumer.xml
直接調(diào)用接口并打印返回值即可。
二.斷點(diǎn)打在哪?
相信很多朋友也很想看源碼,但是不知道從何處下手。處于一種在源碼里面"亂逛"的狀態(tài),一圈逛下來(lái),收獲并不大。
這一小節(jié)我想分享一下我是怎么去看源碼。首先我會(huì)帶著問(wèn)題去源碼里面尋找答案,即有針對(duì)性的看源碼。
如果是這種框架類的,正如上面寫的,我會(huì)先搭建一個(gè)簡(jiǎn)單的Demo項(xiàng)目,然后Debug跟進(jìn)去看。Debug的時(shí)候當(dāng)然需要是設(shè)置斷點(diǎn)的,那么這個(gè)斷點(diǎn)如何設(shè)置呢?
第一個(gè)斷點(diǎn),當(dāng)然毋庸置疑,是打在調(diào)用方法的地方,比如本文中,第一個(gè)斷點(diǎn)是在這個(gè)地方:
接下里怎么辦?
你當(dāng)然可以從第一個(gè)斷點(diǎn)處,一步一步的跟進(jìn)去。但是在這個(gè)過(guò)程中,你發(fā)現(xiàn)了嗎?大多數(shù)情況你都是被源碼牽著鼻子走的。本來(lái)你就只帶著一個(gè)問(wèn)題去看源碼的,有可能你Debug了十分鐘,還沒(méi)找到關(guān)鍵的代碼。也有可能你Debug了十分鐘,問(wèn)題從一個(gè)變成了無(wú)數(shù)個(gè)。
那么我們?cè)趺幢苊獗辉创a牽著四處亂逛呢?我們得找到一個(gè)突破口,還記得我在《很開心,在使用mybatis的過(guò)程中我踩到一個(gè)坑》這篇文章中提到的逆向排查的方法嗎?這次的文章,我再次展示一下該方法。
看源碼之前,我們得冷靜的分析。目標(biāo)要十分明確,就是想要找到Dubbo最小活躍數(shù)算法的具體實(shí)現(xiàn)類以及實(shí)現(xiàn)類的具體邏輯是什么。根據(jù)我們的provider.xml里面的:
很明顯,我們知道loadbalance是關(guān)鍵字。所以我們拿著loadbalance全局搜索,可以看到dubbo包下面的LoadBalance。
這是一個(gè)SPI接口com.alibaba.dubbo.rpc.cluster.LoadBalance:
其實(shí)現(xiàn)類為:
com.alibaba.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance
AbstractLoadBalance是一個(gè)抽象類,該類里面有一個(gè)抽象方法doSelect。這個(gè)抽象方法其中的一個(gè)實(shí)現(xiàn)類就是我們要分析的最少活躍次數(shù)負(fù)載均衡的源碼。
同時(shí),到這里。我們知道了LoadBalance是一個(gè)SPI接口,說(shuō)明我們可以擴(kuò)展自己的負(fù)載均衡策略。抽象方法doSelect有四個(gè)實(shí)現(xiàn)類。這個(gè)四個(gè)實(shí)現(xiàn)類,就是Dubbo官方提供的負(fù)載均衡策略,他們分別是:
ConsistentHashLoadBalance 一致性哈希算法?
LeastActiveLoadBalance 最小活躍數(shù)算法?
RandomLoadBalance ?加權(quán)隨機(jī)算法?
RoundRobinLoadBalance 加權(quán)輪詢算法
我們已經(jīng)找到了LeastActiveLoadBalance這個(gè)類了,那么我們的第二個(gè)斷點(diǎn)打在哪里已經(jīng)很明確了。
目前看來(lái),兩個(gè)斷點(diǎn)就可以支撐我們的分析了。
有的朋友可能想問(wèn),那我想知道Dubbo是怎么識(shí)別出我們想要的是最少活躍次數(shù)算法,而不是其他的算法呢?其他的算法是怎么實(shí)現(xiàn)的呢?從第一個(gè)斷點(diǎn)到第二個(gè)斷點(diǎn)直接有著怎樣的調(diào)用鏈呢?
在沒(méi)有徹底搞清楚最少活躍數(shù)算法之前,這些統(tǒng)統(tǒng)先記錄在案但不予理睬。一定要明確目標(biāo),帶著一個(gè)問(wèn)題進(jìn)來(lái),就先把帶來(lái)的問(wèn)題解決了。之后再去解決在這個(gè)過(guò)程中碰到的其他問(wèn)題。在這樣環(huán)環(huán)相扣解決問(wèn)題的過(guò)程中,你就慢慢的把握了源碼的精髓。這是我個(gè)人的一點(diǎn)看源碼的心得。供諸君參考。
三.模擬環(huán)境
既然叫做最小活躍數(shù)策略。那我們得讓現(xiàn)有的三個(gè)消費(fèi)者都有一些調(diào)用次數(shù)。所以我們得改造一下服務(wù)提供者和消費(fèi)者。
服務(wù)提供者端的改造如下:
PS:這里以權(quán)重為300的服務(wù)端為例。另外的兩個(gè)服務(wù)端改造點(diǎn)相同。
客戶端的改造點(diǎn)如下(for循環(huán)里面的i應(yīng)該為<20):
一共發(fā)送21個(gè)請(qǐng)求:其中前20個(gè)先發(fā)到服務(wù)端讓其hold住(因?yàn)榉?wù)端有sleep),最后一個(gè)請(qǐng)求就是我們需要Debug跟蹤的請(qǐng)求。
運(yùn)行一下,讓程序停在斷點(diǎn)的地方,然后看看控制臺(tái)的輸出:
▲上下滑動(dòng)查看更多
總結(jié)
以上是生活随笔為你收集整理的一文讲透Dubbo负载均衡之最小活跃数算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 牛客小白月赛17
- 下一篇: 删除指定路径下的文件