一、前言
反向代理是 Nginx 最核心的功能之一,通过 upstream 模块实现请求分发到后端服务器。本文将演示 5 种负载均衡策略,每种策略都有完整的配置、测试和结果验证。
二、upstream 基础
基本语法
nginx
upstream backend_name {
# 负载均衡算法
# 默认:round-robin(轮询)
# 后端服务器定义
server 127.0.0.1:9001; # 后端1
server 127.0.0.1:9002; # 后端2
server 127.0.0.1:9003; # 后端3
}
后端服务器参数
| 参数 | 说明 | 默认值 |
|---|---|---|
weight |
权重,值越大分配请求越多 | 1 |
max_fails |
最大失败次数 | 1 |
fail_timeout |
失败统计时间窗口 + 恢复时间 | 10s |
backup |
备份服务器,主服务器全宕机时才启用 | - |
down |
标记为不可用 | - |
三、5 种负载均衡策略详解
策略 1:轮询(Round Robin,默认)
原理: 按顺序轮流分配请求,每个请求依次发给不同的后端。
nginx
upstream backend_rr {
server 127.0.0.1:9001;
server 127.0.0.1:9002;
# 分发顺序:9001 → 9002 → 9001 → 9002 ...
}
测试结果:
请求 1 → Backend-1 (port 9001)
请求 2 → Backend-2 (port 9002)
请求 3 → Backend-1 (port 9001)
请求 4 → Backend-2 (port 9002)
适用场景: 后端性能相近,请求处理时间相近。
策略 2:加权轮询(Weighted Round Robin)
原理: 按权重比例分配请求,权重高的后端收到更多请求。
nginx
upstream backend_weight {
server 127.0.0.1:9001 weight=3; # 权重3,处理 75% 的请求
server 127.0.0.1:9002 weight=1; # 权重1,处理 25% 的请求
}
测试结果:
请求 1 → Backend-1 (port 9001) weight=3
请求 2 → Backend-1 (port 9001) weight=3
请求 3 → Backend-1 (port 9001) weight=3
请求 4 → Backend-2 (port 9002) weight=1
请求 5 → Backend-1 (port 9001) weight=3
请求 6 → Backend-2 (port 9002) weight=1
统计: 6 次请求中,Backend-1 收到 4 次(66.7%),Backend-2 收到 2 次(33.3%),接近 3:1 的比例。
适用场景: 后端性能不均,需要按能力分配流量。
策略 3:最小连接数(Least Connections)
原理: 把请求分配给当前活跃连接数最少的后端。
nginx
upstream backend_least_conn {
least_conn;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
}
适用场景: 长连接场景(如 WebSocket、数据库连接池),避免某个后端堆积太多连接。
策略 4:IP Hash(源地址哈希)
原理: 根据客户端 IP 计算哈希值,同一个 IP 始终打到同一个后端。
nginx
upstream backend_ip_hash {
ip_hash;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
}
测试结果:
连续 6 次请求全部 → Backend-1 (port 9001)
(同一客户端 IP,哈希值相同,始终打到同一台后端)
适用场景: 需要会话保持但没有 Cookie 的场景(如 API 接口)。
策略 5:被动健康检查
原理: Nginx 通过 max_fails 和 fail_timeout 参数实现被动健康检查------当后端连续失败达到阈值时,自动标记为不可用,过一段时间后再恢复。
nginx
upstream backend_health {
server 127.0.0.1:9001 max_fails=3 fail_timeout=30s;
server 127.0.0.1:9002 max_fails=3 fail_timeout=30s;
}
工作流程:
后端正常 → 请求失败 → 失败计数 +1
→ 失败计数达到 max_fails=3
→ 标记为不可用,30 秒内不再转发
→ 30 秒后重试一次
→ 成功 → 恢复可用
→ 失败 → 继续不可用,再等 30 秒
注意: 这是被动健康检查,不需要额外模块。主动健康检查需要 Nginx Plus 或第三方模块(如 Tengine)。
四、反向代理的关键配置
proxy_pass 的两种写法
nginx
# 写法 1:有 / (去掉匹配的前缀)
location /rr/ {
proxy_pass http://backend_rr/;
# 请求 /rr/xxx → 后端收到 /xxx
}
# 写法 2:无 / (保留完整路径)
location /rr/ {
proxy_pass http://backend_rr;
# 请求 /rr/xxx → 后端收到 /rr/xxx
}
请求头传递
nginx
location / {
proxy_pass http://backend_rr/;
# 必须传递的请求头
proxy_set_header Host $host; # 原始 Host 头
proxy_set_header X-Real-IP $remote_addr; # 客户端真实 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 代理链
# 可选传递的请求头
proxy_set_header X-Forwarded-Proto $scheme; # 请求协议
proxy_set_header X-Forwarded-Host $host; # 原始域名
proxy_set_header X-Forwarded-Port $server_port; # Nginx 监听端口
}
五、负载均衡策略对比
| 策略 | 特点 | 适用场景 | 会话保持 |
|---|---|---|---|
| 轮询(RR) | 简单公平,按顺序分发 | 后端性能均等 | ❌ |
| 加权轮询 | 按权重比例分发 | 后端性能不均 | ❌ |
| 最小连接数 | 动态分配,避免堆积 | 长连接/WebSocket | ❌ |
| IP Hash | 同一 IP 到同一后端 | 需要会话保持 | ✅ |
| 随机 | 随机分配,负载均衡 | 测试环境 | ❌ |
六、F5 工程师看反向代理
F5 概念 Nginx 对应
────────────────────────────────────
Pool upstream
Pool Member server
Monitor max_fails + fail_timeout
SNAT Pool proxy_set_header
Persistence ip_hash
OneConnect keepalive_requests
Load Balancing Method balance 指令
关键区别: F5 的 Monitor 是主动健康检查(定时发送探测请求),Nginx 原生的 max_fails 是被动健康检查(基于实际请求的失败来判定)。主动健康检查需要 Tengine 或 Nginx Plus。
七、生产建议
- 默认使用轮询,除非有特殊需求
- 后端性能不均时使用权,避免慢节点拖慢整体
- 需要会话保持使用 IP Hash,但注意 NAT 环境下多个用户可能共享 IP
- 被动健康检查的 max_fails 不要设太小,避免网络抖动导致误判
- proxy_set_header 必须配置,否则后端无法获取客户端真实 IP
下一篇: Nginx HTTP 改写实战:proxy_set_header / rewrite / return / proxy_redirect / sub_filter