IP Hash 在 IPv6 环境下不可用,因原生 ip_hash 仅支持 IPv4,解析 IPv6 地址会失败;应改用 hash $remote_addr consistent,该方案自 Nginx 1.11.0 起支持 IPv4/IPv6 兼容哈希及一致性散列。

IP Hash 在 IPv6 环境下不能直接配置——原生 ip_hash 指令根本不支持 IPv6。它只解析 IPv4 的点分十进制格式,遇到冒号分隔的 IPv6 地址会解析失败,轻则启动报错(如 [emerg] invalid parameter "ip_hash"),重则配置校验不通过或请求路由异常。
为什么 ip_hash 不适用于 IPv6
Nginx 官方文档明确说明:ip_hash 仅适用于 IPv4。其底层实现中,IPv4 地址取前 3 个字节哈希,IPv6 地址虽有部分旧版本尝试兼容(如 1.7.2+ 开始识别完整地址),但并非标准支持,行为不可靠且不保证一致性。实际运行中,IPv6 请求可能被忽略哈希逻辑、退化为轮询,或因地址格式误判导致 502 错误。
- IPv6 地址结构(如
2001:db8::1)与 ip_hash 预期输入不匹配 - 即使配置成功,不同 Nginx 版本对 IPv6 的处理差异大,线上环境难稳定
- ip_hash 本身不支持
consistent参数,无法缓解扩容导致的会话漂移问题
正确替代方案:用 hash $remote_addr consistent
这是目前最可靠、官方推荐的 IPv4/IPv6 兼容方案,从 Nginx 1.11.0 起原生支持:
- 自动识别并哈希完整 IPv4 或 IPv6 地址(无需截取前缀或掩码)
-
consistent启用一致性哈希,增删后端节点时仅少量请求重散列,大幅降低会话丢失风险 - 支持与
weight、backup、健康检查等参数共存
配置示例:
upstream backend {
hash $remote_addr consistent;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server [2001:db8::1]:8080; # 支持 IPv6 后端地址(方括号包裹)
}确保真实客户端 IP 被正确识别
若前端有 CDN、反向代理或负载均衡器,$remote_addr 默认是代理的 IP,会导致所有 IPv6 用户哈希到同一后端。必须启用 real_ip 模块:
- 在 http 块中配置可信代理段:
set_real_ip_from 2001:db8::/32;(按实际代理 IPv6 段填写) - 指定真实 IP 来源头:
real_ip_header X-Forwarded-For;或X-Real-IP - 确认日志中
$remote_addr字段已显示真实 IPv6 地址(如2001:db8::abcd)
验证是否生效
添加日志格式,观察 IPv6 请求是否稳定命中同一后端:
- 定义日志:
log_format ipv6_hash '$remote_addr — $upstream_addr — $time_local'; - 启用日志:
access_log /var/log/nginx/ipv6_access.log ipv6_hash; - 用不同 IPv6 客户端(如手机开启 IPv6 网络、或 curl -6 --proxy)发起多次请求,检查日志中
$upstream_addr是否不变


















