验证ip_hash路由收敛性的关键是确认同一真实客户端ip请求稳定落到同一后端服务器,需确保真实ip透传与识别、设计可追踪压测流量、通过后端日志统计ip与实例映射分布,并辅以nginx日志交叉验证。

要验证 ip_hash 在全链路压测环境下的路由收敛表现,关键不是“看它有没有分配”,而是确认同一真实客户端 IP 的请求是否稳定落到同一台后端服务器,且这个稳定性在多层代理、高并发、节点故障等真实场景下依然成立。
一、确保真实 IP 能被正确识别
ip_hash 失效的首要原因,是 Nginx 拿到的 $remote_addr 是最后一跳代理(如 SLB、CDN 或前置 Nginx)的内网地址,而非用户真实 IP。压测前必须完成以下配置:
- 上游所有代理(包括 CDN、云 LB、前置 Nginx)必须透传 X-Forwarded-For,格式为
ClientIP, Proxy1IP, Proxy2IP - 在当前 Nginx 的 http 或 upstream 上下文中,明确声明可信代理段:
set_real_ip_from 10.0.0.0/8;<br>set_real_ip_from 172.16.0.0/12;<br>set_real_ip_from 192.168.0.0/16;<br>real_ip_header X-Forwarded-For;
- 启用后,$remote_addr 将自动替换为最左侧的客户端 IP,ip_hash 才真正基于真实源地址计算
二、设计可验证的压测流量模式
不能只用随机 IP 压测——那样无法观察“收敛”。应构造具备标识性、可追踪的请求流:
- 使用固定数量的真实客户端 IP(例如 100 个),每个 IP 发起持续、高频的请求(如每秒 5–10 QPS),模拟真实用户会话
- 在请求头中加入唯一标记,例如:
X-Test-ID: user-123,便于日志关联和后端识别 - 避免使用本地 host 文件或 curl -H "X-Forwarded-For: xxx" 伪造——这绕过了真实链路,无法验证代理透传与 real_ip 配置是否生效
- 推荐用 JMeter 或 k6 控制 IP 源:通过多台压测机 + NAT 网关,或使用支持 IP 轮换/固定源的代理池
三、从后端日志直接验证收敛性
这是最可靠的方式,不依赖 Nginx 自身指标(如 upstream_addr 不体现真实哈希结果):
- 后端服务需记录每条请求的两个关键字段:remote_addr(来自 Nginx 的 $remote_addr) 和 X-Real-IP(若你额外透传)
- 压测运行 2–5 分钟后,统计每个客户端 IP 对应的后端实例(如 hostname 或 pod IP)分布:
→ 若 100 个 IP 全部只命中 1 台后端,说明 ip_hash 完全未生效(大概率 real_ip 配置错误)
→ 若每个 IP 都稳定落在某一台,且不同 IP 分布相对均匀(比如 3 台后端分别承接约 30/35/35 个 IP),说明收敛正常 - 特别检查边界情况:当某台后端宕机时,原属于它的 IP 是否整体漂移到另一台(ip_hash 默认不自动重平衡,但会剔除失效节点后重新哈希)
四、配合 Nginx 日志做辅助交叉验证
在 access_log 中添加 upstream 相关变量,用于快速排查链路异常:
- 配置日志格式:
log_format main '$remote_addr - $http_x_forwarded_for [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_addr $upstream_http_x_backend'; - 重点看:
→$remote_addr是否已变成公网 IP(而非 10.x/172.x 内网地址)
→$http_x_forwarded_for是否完整携带多级代理链
→$upstream_addr是否对同一 $remote_addr 始终返回相同后端地址 - 用 awk + sort 快速统计:
awk '{print $1, $12}' access.log | sort | uniq -c | sort -nr | head -20(假设 $1 是 $remote_addr,$12 是 $upstream_addr)
不复杂但容易忽略:收敛性测试的本质,是把“IP → 后端”的映射关系从黑盒变白盒。只要真实 IP 正确还原、压测流量可追溯、后端日志可聚合,结论就清晰可靠。











