真实nat环境下ip_hash分流是否合理,需先验证$remote_addr是否为代理ip:若集中为少数公网ip而$http_x_forwarded_for多样,则属典型nat场景;再用ab/wrk模拟单出口多用户请求,对比ip_hash与轮询的后端负载分布及qps、连接数是否倾斜。

直接用真实流量或模拟请求观察 ip_hash 在 NAT 环境下的实际分流效果,比看理论更可靠。关键不是“能不能分”,而是“分得是否合理”——尤其当大量用户共用一个出口 IP 时。
确认你面对的是真实 NAT 场景
先查日志,验证 Nginx 收到的到底是不是用户真实 IP:
- 在
http块里加一句:log_format debug '$remote_addr - $http_x_forwarded_for - $request_uri';,再把access_log切到这个格式 - 压测或真实访问后,看日志里
$remote_addr是否集中为少数几个公网 IP(比如全是120.236.10.1),而$http_x_forwarded_for里有多个不同 IP —— 这就是典型的 CDN/WAF/NAT 覆盖现象 - 如果
$remote_addr已经是真实客户端 IP,那 NAT 不是问题,后续测试可跳过“提取真实 IP”环节
用 ab 或 wrk 模拟多用户、单出口 IP 的并发请求
模拟校园网、运营商共享出口这类典型场景,重点看后端节点负载是否严重倾斜:
- 用
ab -n 2000 -c 200 -H "X-Forwarded-For: 192.168.1.100" http://your-domain/发起请求,固定伪造一个源 IP,观察三台后端 access.log 中各自收到多少请求(应基本全落在同一台) - 再开多个终端,分别用不同
X-Forwarded-For(如192.168.1.101、192.168.1.102…),每组跑 200 请求,统计各后端请求数分布 - 对比轮询策略下的分布:去掉
ip_hash,只留server列表,重复上述步骤,看是否明显更均匀
监控后端节点的实际 QPS 和连接数
分流是否“不均”,不能只看请求计数,还要看服务端真实压力:
- 在每台后端服务器上运行
curl http://localhost:8080/metrics(如有 Prometheus metrics)或简单用netstat -an | grep :8080 | wc -l统计 ESTABLISHED 连接数 - 用
watch -n 1 'ss -s | grep "tcp:"'观察 Nginx 本机连接状态,确认是否有某台后端连接数长期高出 2–3 倍 - 设置告警阈值:例如某节点 QPS > 全局均值 × 2.5,就说明
ip_hash在当前 NAT 分布下已造成明显不均
快速验证 real_ip 模块是否生效
如果你已配置 set_real_ip_from 和 real_ip_header,必须验证它真正在起作用:
- 临时在 upstream 块里改用
hash $remote_addr consistent;替代ip_hash - 同时在 server 块中加
add_header X-Used-IP $remote_addr; - 发起带
X-Forwarded-For的请求,检查响应头里的X-Used-IP是不是你期望的真实客户端 IP,而不是中间代理 IP - 只有这个值正确了,后续基于
$remote_addr的哈希才真正有意义











