負載均衡指令least_conn的含義,按照nginx文檔的說法:
Specifies that a group should use a load balancing method where a request is passed to the server with the least number of active connections, taking into account weights of servers. If there are several such servers, they are tried in turn using a weighted round-robin balancing method.
意思是請求將被傳遞給當前擁有最少活躍連接的server,同時考慮權重weight的因素。
但權重因素是如何被考慮進去的呢?
查看nginx源碼,在http模塊ngx_http_upstream_least_conn_module.c中,決定“最少連接”的邏輯是這樣的:
if (best == NULL || peer->conns * best->weight < best->conns * peer->weight)
{
best = peer; //選擇peer為當前server
many = 0;
p = i;
} else if (peer->conns * best->weight == best->conns * peer->weight) {
many = 1;
}
其中peer->conns * best->weight < best->conns * peer->weight
這一段很關鍵,我們做個不等式推到,就知道其等價於下面的不等式:
peer->conns/peer->weight < best->conns/best->weight
可見比較的其實是conns/weight的大小。上面代碼的邏輯就是,當peer的conns/weight小於best時,就把peer賦值給best。因此最終best是選取的conns/weight的最小的那個。
因此least_conn指令實際的含義就是,選取活躍連接數與權重weight的比值最小者為下一個處理請求的server。當然,上一次已選的server和已達到最大連接數的server照例不在選擇的范圍。
例如一個upstream有三台server:
upstream backend {
zone backends 64k;
least_conn;
server 10.10.10.2 weight=2;
server 10.10.10.4 weight=1;
server 10.10.10.6 weight=1;
}
假如上一個請求選擇了第二台10.10.10.4,下一個請求到來,通過比較剩下可用的server的conns/weight值來決定選哪一台。
如果10.10.10.2連接數為100,10.10.10.6連接數為80,因為權重分別是2和1,因此計算結果
100/2=50, 80/1 =80。因為 50 < 80 所以選擇第一台而不選第三台。盡管連接數第一台要大於第三台。