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