负载均衡指令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 所以选择第一台而不选第三台。尽管连接数第一台要大于第三台。