要让Nginx轮询负载均衡正确传递真实客户端IP,关键是透传请求头并确保后端识别一致:需在location中配置proxy_set_header X-Real-IP $remote_addr、X-Forwarded-For $proxy_add_x_forwarded_for和Host $http_host;upstream按默认轮询定义即可;后端须主动读取对应头,多层代理时取X-Forwarded-For首个非私有IP。

要让 Nginx 轮询负载均衡在使用 upstream 模块时正确传递真实客户端 IP,关键不是改算法,而是确保请求头透传 + 后端识别逻辑一致。轮询本身不干扰 IP 传递,出问题的环节通常在代理链路中头信息被覆盖或丢失。
必须设置的 proxy_set_header 指令
在引用 upstream 的 location 块中,至少要显式设置以下三行:
- proxy_set_header X-Real-IP $remote_addr; —— 把 Nginx 接收到的真实客户端 IP(非代理 IP)写入该头
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; —— 追加式记录转发路径,兼容多层代理
- proxy_set_header Host $http_host; —— 保持原始 Host,避免后端路由或证书校验异常
upstream 定义本身无需特殊改动
轮询是 upstream 的默认行为,只要按标准方式定义即可:
- 放在
http{ }块内,不能嵌套在 server 或 location 中 - 每个
server行带明确端口(如server 10.0.0.5:8000;),避免隐式依赖 80 端口 - 不加
weight、ip_hash等参数,就自动启用轮询
后端服务需主动读取对应请求头
Nginx 只负责“传”,后端得“收”。常见框架处理方式:
- Java Spring Boot:配置
server.forward-headers-strategy=framework,并信任 Nginx 的 X-Forwarded-For - Node.js(Express):启用
app.set('trust proxy', true),再用req.ip或req.headers['x-real-ip'] - Python Flask:设
app.config['TRUSTED_PROXIES'] = ['127.0.0.1'],再读request.headers.get('X-Real-IP')
多层代理场景要特别注意
如果 Nginx 前面还有 CDN、WAF 或另一台 Nginx,X-Forwarded-For 可能被多次追加。此时建议:
- 前端代理统一用
X-Forwarded-For传递最左 IP(即最原始客户端 IP) - Nginx 配置中不要覆盖,只用
$proxy_add_x_forwarded_for追加自身 IP - 后端解析时取
X-Forwarded-For的第一个非私有地址,而非末尾


















