★ Nginx 反向代理怎么做负载均衡?有哪些调度策略与健康检查方式?
结论先行:反向代理是“服务端代理,客户端无感知”,Nginx 通过 upstream 块定义后端组并默认轮询分发,策略包括轮询、加权轮询、ip_hash、least_conn、url_hash 等;后端可用性靠被动健康检查(max_fails/fail_timeout)兜底,主动探测与动态摘除需配合第三方模块或 Nginx Plus。
一、正向 vs 反向代理
| 对比 | 正向代理 | 反向代理 |
|---|
| 代理对象 | 代理客户端 | 代理后端服务器 |
| 典型场景 | 访问管控、出口统一 | 负载均衡、隐藏后端 |
| 客户端感知 | 需要配置 | 无感知,只看到 Nginx |
二、upstream 常见策略
| 策略 | 关键字 | 适用场景 |
|---|
| 轮询 | 默认 | 后端无状态、性能相近 |
| 加权轮询 | weight=2 | 后端机器性能不同 |
| IP 哈希 | ip_hash | 需要会话粘滞 |
| 最小连接 | least_conn | 请求处理耗时差异大 |
| URL 哈希 | hash $request_uri | 同类请求固定后端、缓存友好 |
三、最小可用配置
upstream backend {
server 10.0.0.11:8080 weight=3 max_fails=2 fail_timeout=10s;
server 10.0.0.12:8080 weight=1;
keepalive 32; # 与后端的长连接复用
}
server {
listen 80;
location /api/ {
proxy_pass http://backend;
proxy_next_upstream error timeout http_502; # 失败自动换下一台
proxy_connect_timeout 2s;
proxy_read_timeout 10s;
}
}
四、健康检查怎么理解
- 被动检查:转发失败累计 max_fails 次后,fail_timeout 内不再转发该节点,恢复需等待或成功探活。
- 主动检查:Nginx Plus 或 Lua/第三方模块定期发探测请求,不依赖真实流量。
- 动态感知:后端扩容/缩容通过 Consul/Nacos + 同步模块(如 nginx-upsync)动态更新节点。
常见追问与记忆点
- 追问:ip_hash 能当会话保持吗?同 IP 固定同一后端,但出口统一或 IP 变化时会失效,正规做法是网关会话或 Redis 集中会话。
- 追问:Nginx 能当业务网关吗?它能做七层转发,但鉴权/灰度/流控更适合放 API 网关(见第 38 章)。
- 记忆点:默认轮询、weight 调比例、least_conn 跟耗时、哈希做粘滞;故障靠 max_fails + fail_timeout 摘除。