一、一个让我困惑了三年的问题
做后端开发的同学,大概都配过Nginx负载均衡。配置不难,几行upstream搞定:
upstream backend { server 192.168.1.1:8080 weight=5; server 192.168.1.2:8080 weight=3; server 192.168.1.3:8080 weight=1; }weight=5的机器性能好,就让它多扛点请求。挺合理。
但有个问题一直困扰我:Nginx到底怎么根据权重分请求的?
最直觉的想法——连续发5个请求给权重5的服务器,再发3个给权重3的,最后1个给权重1的。但仔细想想不对:这么干的话,权重高的机器会在短时间内被"打爆",其他机器却在旁边闲着。
那Nginx怎么做到既按权重分配、又让请求分布足够"平滑"呢?
这个问题我琢磨了三年。直到最近读了Nginx源码,才发现里面藏着一个精妙绝伦的算法——平滑加权轮询(Smooth Weighted Round-Robin)。
今天把这个算法彻底讲清楚。
二、负载均衡的本质:分蛋糕问题
深入源码之前,先退一步,搞清楚负载均衡到底在解决什么。
想象你是餐厅老板,手底下三个服务员:
- 小王:手脚最麻利,能同时服务5桌客人
- 小李