nginx 的轮询、加权、ip_hash、hash、least_conn 实际怎么分布?后端速度不一样时 least_conn 好在哪?自己写一个平滑加权轮询,和 nginx 的选择顺序一样吗?这篇用三个后端逐项量出来。
指令 | A | B | C -----------------------------+-----+-----+---- 默认(轮询) | 234 | 233 | 233 weight=5:1:1 | 500 | 100 | 100 weight=3:2:1 | 350 | 233 | 117 ip_hash(全是 127.0.0.1) | 0 | 0 | 700 hash $http_x_user | 239 | 214 | 247 hash $http_x_user consistent | 252 | 220 | 228 random | 252 | 223 | 225 random two least_conn | 222 | 243 | 235
权重按比例分,哈希按键散开;ip_hash 在 client 地址全相同时没有负载均衡的作用。
指令 | A(10 ms) | B(10 ms) | C(100 ms) | 延迟中位数 | p99 | 总吞吐 ----------------------+----------+----------+-----------+-------+--------+------ 轮询 | 534 | 533 | 533 | 15 ms | 111 ms | 325/s least_conn | 746 | 739 | 115 | 15 ms | 110 ms | 503/s random two least_conn | 724 | 749 | 127 | 15 ms | 110 ms | 471/s
后端速度不一样时,least_conn 让慢节点少收请求,总吞吐更高。
nginx 配置 | nginx 真实的前 14 个选择 | 手写 SWRR 的前 14 个 | 比对 -------------+-------------------+-----------------+--- weight=5:1:1 | AABACAAAABACAA | AABACAAAABACAA | 相同 weight=3:2:1 | ABACBAABACBAAB | ABACBAABACBAAB | 相同 weight=1:1:1 | ABCABCABCABCAB | ABCABCABCABCAB | 相同 手写的普通轮询(RR)就是 i % n;加权轮询如果简单地把每个节点重复 weight 次再循环,会得到 AAAAABC 这样的序列(同一个节点连续被选很多次),平滑加权轮询把它们错开 朴素的“重复 weight 次”序列(5:1:1)前 14 个: AAAAABCAAAAABC
把节点错开,不是连续选同一个;手写版本和 nginx 的顺序完全一致。