1.算法介紹
ip_hash算法的原理很簡單,根據請求所屬的客戶端IP計算得到一個數值,然後把請求發往該數值對應的後端。
所以同一個客戶端的請求,都會發往同一臺後端,除非該後端不可用了。ip_hash能夠達到保持會話的效果。
ip_hash是基於round robin的,判斷後端是否可用的方法是一樣的。
2.算法核心部分
2.1. 第一步,根據客戶端IP計算得到一個數值。
for (i = 0; i < 3; i++) {
hash = (hash * 113 + iphp->addr[i]) % 6271; //iphp->addr[i]爲ip的點分十進制法的第i段
}
hash3就是計算所得的數值,它只和初始數值hash0以及客戶端的IP有關。
for循環 i取 012三個值,而ip的點分十進制表示方法將ip分成四段(如:192.168.1.1),但是這裏循環時只是將ip的前三個端作爲參數加入hash函數。這樣做的目的是保證ip地址前三位相同的用戶經過hash計算將分配到相同的後端server。
作者的這個考慮是極爲可取的,因此ip地址前三位相同通常意味着來着同一個局域網或者相鄰區域,使用相同的後端服務讓nginx在一定程度上更具有一致性。
2.2. 第二步,根據計算所得數值,找到對應的後端。
w = hash3 % total_weight;
while (w >= peer->weight) {
w -= peer->weight;
peer = peer->next;
p++;
}
total_weight爲所有後端權重之和。遍歷後端鏈表時,依次減去每個後端的權重,直到w小於某個後端的權重。
選定的後端在鏈表中的序號爲p。因爲total_weight和每個後端的weight都是固定的,所以如果hash3值相同,
則找到的後端相同。
參考: