负载均衡是流量分发的中枢,也是高可用架构的第一道闸门。Nginx 负载均衡凭借内置的 upstream 模块,不用引入额外组件,就能用极低的运维成本把请求均匀摊到多台后端服务器。本文从 upstream 基础配置一路讲到加权轮询、会话保持、被动健康检查与连接复用,并给出可直接抄进生产 nginx.conf 的片段。无论你是单机扛不住想横向加机器,还是要做灰度发布降低上线风险,这套 Nginx 负载均衡方案都能立刻派上用场。
一、为什么需要 Nginx 负载均衡
单台应用服务器总有性能天花板,CPU、内存或带宽任一打满,整站响应就跟着抖。大促、突发流量或单点故障,最容易在这类节点上集中爆发。把多台后端塞进同一个 upstream 池,Nginx 在七层(HTTP)把请求智能转发出去,既摊薄了单台压力、提升整体吞吐,又能在某台宕机时自动绕开它,避免雪崩式连锁故障。配合此前讲过的 Nginx 反向代理 思路,负载均衡只是把”单一上游地址”换成了”上游组”,心智模型完全一脉相承,迁移成本极低。
二、upstream 基础配置:从轮询到加权
最朴素的做法是默认轮询,每个后端轮流接活,适合机器完全对等的场景。一旦后端配置参差不齐,就得给机器加 weight:性能强的多分流量,配置弱的少分,集群整体利用率立刻上来,也不会出现弱机被压垮、强机在摸鱼的现象。
http {
upstream app_pool {
server 10.0.0.11:8080 weight=3;
server 10.0.0.12:8080 weight=2;
server 10.0.0.13:8080 weight=1;
}
server {
listen 80;
location / {
proxy_pass http://app_pool;
}
}
}
加权轮询的调度比例
上面的 weight=3:2:1 意味着每 6 个请求里,11 号机器吃 3 个、12 号吃 2 个、13 号吃 1 个,长期统计上严格按权重分配。新机器上线或老机器降配时,调 weight 比改架构轻松得多,它也是后面灰度放量手法的基础。
三、四种负载均衡策略怎么选
除了轮询,Nginx 内置多种分流算法,按业务特征选对能少踩很多坑。下面这张表是选型速查:
| 策略 | 指令 | 适用场景 |
|---|---|---|
| 轮询 | 默认 | 后端完全对等 |
| 加权轮询 | weight | 机器配置不均 |
| IP 哈希 | ip_hash | 需会话保持、无共享会话 |
| 最少连接 | least_conn | 请求耗时差异大 |
upstream app_pool {
ip_hash; # 同一客户端固定落到同一后端
server 10.0.0.11:8080;
server 10.0.0.12:8080;
}
upstream api_pool {
least_conn; # 优先发给连接数最少的后端
server 10.0.0.21:8080;
server 10.0.0.22:8080;
}
ip_hash 适合还没上分布式会话的老系统,按客户端 IP 做粘性;least_conn 则适合请求耗时悬殊的接口,谁闲发给谁,比盲目轮询更均衡。注意 ip_hash 下若某节点被摘,哈希环会重排,可能让一批用户”换台机器”,所以最好配合共享会话一起用。
四、被动健康检查:自动踢掉宕机节点
默认 Nginx 不会主动去 ping 后端探测存活,只能靠转发失败的累积次数来推断节点状态。用 max_fails 和 fail_timeout 做被动健康:在 fail_timeout 时间窗口内,某节点失败次数超过 max_fails,就暂时标记为不可用,后续流量自动绕开,等窗口过期后再试探性放回。这套机制对瞬时抖动很友好,能自动屏蔽短暂抽风的节点。
upstream app_pool {
server 10.0.0.11:8080 max_fails=3 fail_timeout=30s;
server 10.0.0.12:8080 max_fails=3 fail_timeout=30s;
}
被动检查够用但有盲区:它只在有真实流量时才发现故障,没流量时节点悄悄挂了也不会被摘除,相当于”哑火”。若想主动探活,商业版 Nginx Plus 提供 health_check 指令;开源党可以用 Docker 跑一个 nginx-upsync-module,或在前层接 keepalived 加自研探针,周期性探活再同步到 upstream。
五、proxy_next_upstream:一次失败自动重试
单台后端偶发超时或返回 502,与其让用户直接看到错误页,不如让 Nginx 把请求悄悄转给下一个健康节点重试一次。proxy_next_upstream 就是干这个的,它是开源方案里最接近”主动健康”的兜底,强烈建议生产必配。配合收紧的超时时间,能在后端抖动时显著抬升成功率。
location / {
proxy_pass http://app_pool;
proxy_next_upstream error timeout http_502 http_503;
proxy_connect_timeout 3s;
proxy_read_timeout 10s;
}
这里有个坑:proxy_next_upstream 对写请求(POST)也可能重试,若后端接口不幂等,可能造成重复下单。对交易类接口建议只放行 error/timeout,或后端自己做幂等键,别盲目全开。
六、生产排障清单
负载不均或健康检查不生效时,按这张表逐项核对,八成问题都能定位:
| 现象 | 可能原因 | 对策 |
|---|---|---|
| 流量只打到一台 | 误用 ip_hash | 改用默认轮询或 least_conn |
| 节点被频繁剔除 | max_fails 太小 | 调大阈值或延长 fail_timeout |
| 502 增多 | 后端超时 | 收紧 proxy_next_upstream 并扩容 |
| 会话串号 | 无共享会话 | 加 ip_hash 或接 Redis 会话 |
七、连接复用:别让 upstream 成新瓶颈
负载均衡接上后,Nginx 与后端之间默认每条请求新建一条 TCP 连接,高并发下握手与 TIME_WAIT 开销反而拖慢整体。开启 keepalive 让连接复用,能明显降延迟、省文件描述符,是上线前最该补的一笔优化。
upstream app_pool {
server 10.0.0.11:8080;
server 10.0.0.12:8080;
keepalive 32;
}
location / {
proxy_pass http://app_pool;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
keepalive 32 表示每个 worker 最多保留 32 条空闲长连接;它必须配合 proxy_http_version 1.1 并清空 Connection 头才会生效。注意这只对”Nginx 到上游”生效,和”客户端到 Nginx”的 keepalive 是两回事,别混为一谈。
八、灰度发布:用 weight 逐步放量
上新版本最怕”全量即翻车”。把新机器先设成小 weight,比如旧集群 weight=10、新机 weight=1,只放约 1/11 的流量做真实验证;观察错误率与耗时平稳后,再逐步把 weight 调平。整个过程不用改架构,只动数字,回滚也只需把新机 weight 调回 0,是中小团队最省心的灰度姿势。
另外,负载均衡器本身也是单点,公网入口建议叠一层 Linux 安全加固 与 WAF 规则,别让转发层成为突破口。涉及配置下发可纳入 GitHub Actions 做灰度与回滚,避免一次改错全员掉线。
总结
Nginx 负载均衡的核心就是 upstream 池加合适的分流策略,再用被动健康检查、proxy_next_upstream 与 keepalive 兜底容错。从轮询起步,按机器配置上 weight,按业务加 ip_hash 或 least_conn,用排障清单守住稳定性,最后借 weight 做灰度——这就是一套能直接上生产的 Nginx 负载均衡落地方案。




