Nginx加權輪詢算法


記錄一下nginx加權分配算法。

nginx可以指定輪詢幾率,weight和訪問比率成正比,用於后端服務器性能不均的情況。
例如:

upstream backend {
  server a weight=6;
  server b weight=3;
  server c weight=1;
}

按照配置,每有10次請求,其中6個會轉發到a服務器,3個轉發到b服務器,1個轉發到c服務器。

每個服務器都有三個權重變量,先解釋下它們的含義。

(1) weight

配置文件中指定的該服務器的權重,這個值是固定不變的。

(2) effective_weight

服務器的有效權重,初始值為weight。

在釋放服務器時,如果發現和某服務器的通信過程中發生了錯誤,就減小它的effective_weight。
此后有新的請求過來時,在選取該服務器的過程中,再逐步增加effective_weight,最終又恢復到weight。
之所以增加這個字段,是為了當服務器發生錯誤時,降低其權重。

(3) current_weight

服務器目前的權重,初始為0,之后會動態調整。

那么如何動態調整呢?

nginx每次選取服務器時:

  1. 先遍歷集群中所有服務器,將每個服務器的current_weight增加它的effective_weight,
  2. 再累加所有服務器的effective_weight,保存為total。
  3. 判斷當前服務器的current_weight是否最大,是則選中該服務器,然后把它的current_weight減去total。不是則不會被選中,current_weight也就不用減了。

弄清了三個weight字段的含義后,加權輪詢算法可描述為:

  1. 對於每個請求,遍歷集群中的所有可用服務器,對於每個服務器執行:current_weight += effecitve_weight。
  2. 累加所有effective_weight,保存為total。
  3. 選出current_weight最大的服務器,作為本次選定的服務器。
  4. 對於本次選定的服務器,執行:current_weight -= total。

下面以表格形式記錄其過程:

請求次數 開始current_weight 增加effective_weight 累加total 選中服務器 選中后current_weight
1 [0, 0, 0] [6, 3, 1] 10 a [-4, 3, 1]
2 [-4, 3, 1] [2, 6, 2] 10 b [2, -4, 2]
3 [2, -4, 2] [8, -1, 3] 10 a [-2, -1, 3]
4 [-2, -1, 3] [4, 2, 4] 10 a [-6, 2, 4]
5 [-6, 2, 4] [0, 5, 5] 10 b [0, -5, 5]
6 [0, -5, 5] [6, -2, 6] 10 a [-4, -2, 6]
7 [-4, -2, 6] [2, 1, 7] 10 c [2, 1, -3]
8 [2, 1, -3] [8, 4, -2] 10 a [-2, 4, -2]
9 [-2, 4, -2] [4, 7, -1] 10 b [4, -3, -1]
10 [4, -3, -1] [10, 0, 0] 10 a [0, 0, 0]

可以看到,選中服務器依次為[a, b, a, a, b, a, c, a, b, a]。

a,b,c分別被選中了6,3,1次,正好是符合其權重值的;
服務器a雖然權重大,但沒有被連續選取,不會對a服務器連續請求;
經過10次請求后,a,b,c的當前權重current_weight又全部歸0,如此便可循環往復。

ps: 這里我們發現total永遠都是10,因為這里假定服務器都沒有發生故障或返回錯誤,其effective_weight不變。實際中如果服務器發生了錯誤,nginx當然也會進行降權處理,total也會變啦。這里我們學習一下正常算法,出錯的情況就先不展開了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM