深色模式
Nginx 负载均衡策略
摘要:Nginx 的 upstream 支持多种调度算法:默认轮询、weight 加权、ip_hash 会话保持、least_conn 最少连接。本文给出每种算法的最小可运行配置、适用场景与验证方法,并说明开源版健康检查的取舍。
适用环境
bash
nginx -v # 确认 Nginx 已安装
sudo nginx -T | grep -n 'upstream' # 查看已有 upstream 定义
# 准备 3 个可区分的后端(返回不同主机名/端口)
for p in 8080 8081 8082; do
(cd /tmp && python3 -m http.server $p >/dev/null 2>&1 &)
done1
2
3
4
5
6
7
2
3
4
5
6
7
操作步骤
1. 默认轮询(round-robin)
nginx
upstream app_rr {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}1
2
3
4
5
2
3
4
5
适用于所有后端配置相同、请求无状态的场景,流量近似均分。
2. 加权轮询(weight)
nginx
upstream app_wrr {
server 127.0.0.1:8080 weight=3; # 约 3/6 流量
server 127.0.0.1:8081 weight=2; # 约 2/6
server 127.0.0.1:8082 weight=1; # 约 1/6,可用作灰度小流量
}1
2
3
4
5
2
3
4
5
新旧机器混部时按性能配比;也可把 weight=1 的机器当作金丝雀节点。
3. ip_hash(会话保持)
nginx
upstream app_iphash {
ip_hash;
server 127.0.0.1:8080;
server 127.0.0.1:8081;
server 127.0.0.1:8082 down; # down 表示永久下线,不参与调度
}1
2
3
4
5
6
2
3
4
5
6
按客户端 IP 前三个字节哈希,同一 IP 固定打到同一后端。适用于后端本地保存会话、又不方便接入共享 Session 的遗留系统。
4. least_conn(最少连接)
nginx
upstream app_lc {
least_conn;
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}1
2
3
4
5
2
3
4
5
把新请求给当前活跃连接最少的后端,适合长连接或请求耗时差异大的接口。
5. 被动健康检查参数
nginx
upstream app_rr {
server 127.0.0.1:8080 max_fails=3 fail_timeout=10s; # 10s 内失败 3 次摘除 10s
server 127.0.0.1:8081 max_fails=3 fail_timeout=10s backup; # backup:主节点全挂才启用
}1
2
3
4
2
3
4
6. 应用并重载
bash
sudo nginx -t && sudo systemctl reload nginx1
DANGER
ip_hash 与 weight 同时使用时权重会被忽略;且一旦用了 ip_hash,后端频繁扩容/缩容会导致大量会话重新分布。有状态服务请优先把 Session 外移到 Redis,而不是依赖 ip_hash。
验证
bash
# 1) 轮询:连续 6 次请求,观察后端访问日志是否交替出现
for i in $(seq 1 6); do curl -s -o /dev/null http://127.0.0.1/; done
sudo tail -n 6 /var/log/nginx/access.log | awk '{print $NF}'
# 2) 加权:统计 60 次请求落到各后端的次数(后端日志计数)
for i in $(seq 1 60); do curl -s -o /dev/null http://127.0.0.1/; done
# 3) ip_hash:同一来源 IP 多次请求,access.log 的 upstream 字段应固定
for i in $(seq 1 5); do curl -s -o /dev/null http://127.0.0.1/; done
# 4) 摘除验证:停掉一个后端再请求,应不再返回 502
sudo nginx -t && sudo systemctl reload nginx1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
常见坑
WARNING
ip_hash 在 Nginx 前面还挂了一层负载均衡或 CDN 时,$remote_addr 全都是代理的 IP,结果所有请求都打到同一台后端。此时应改用 hash $http_x_forwarded_for consistent;。
WARNING
backup 节点只有在所有主节点都不可用时才启用。如果你期待它"平时也分担流量",那它不是 backup,应直接配成普通节点。
DANGER
max_fails=0 表示永不摘除故障节点。设置了它,后端挂掉会持续给用户返回 502,别把它和"不限制失败次数"搞混——要禁用检查就写 max_fails=0,要快速摘除就写小值如 max_fails=2 fail_timeout=5s。