ip_hash;可启用基于客户端IP的会话保持,但仅适用于内网/IP稳定环境,需配合real_ip配置、禁用buffering、延长超时等调优,且不支持权重与动态扩缩容。

直接在 upstream 块里加 ip_hash; 就能启用基于客户端 IP 的会话保持,但光写这一行远远不够——它只在特定条件下有效,用错反而导致会话丢失、负载不均或 CDN 下完全失效。
ip_hash 的核心机制和适用前提
它对客户端 IPv4 地址取前三个字节(如 192.168.1.x 视为同一 IP)、IPv6 取完整地址做哈希,再对当前后端节点数取模,固定路由到某台服务器。这意味着:
- 必须是内网环境或客户端 IP 稳定(如企业办公网、固定出口 NAT)
- 后端服务得自己存 Session(比如 Tomcat 内存 Session、Spring Boot 默认 Session)
- 不能有频繁扩缩容——增减一台 server,所有 IP 的哈希映射都会偏移,大量用户会话“漂移”
- 不适用于公网移动用户、多层代理或 CDN 接入场景
基础配置写法与位置要求
ip_hash; 必须放在 upstream 块的最前面,且不能和其它 hash 指令(如 hash $cookie_session)共存,也不能和 weight、backup、max_fails 等参数混用——这些配置一旦开启 ip_hash 就会被忽略。
正确示例:
upstream app_backend {
ip_hash;
server 10.0.2.10:8080;
server 10.0.2.11:8080;
server 10.0.2.12:8080;
}
server {
listen 80;
location / {
proxy_pass http://app_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
真实环境必须补上的关键配置
如果上游有可信代理(如 SLB、CDN 或 Nginx 自身前置),$remote_addr 会变成代理 IP,必须还原真实客户端 IP:
- 添加 set_real_ip_from 声明可信代理网段(如 set_real_ip_from 192.168.10.0/24;)
- 设置 real_ip_header 指定转发头(通常为 X-Forwarded-For 或 X-Real-IP)
- 否则 ip_hash 实际按代理 IP 哈希,所有请求都打到同一台后端
生产级文件类业务要同步调优
单纯 ip_hash 对上传、断点续传等场景不够用,还需配套调整:
- 关闭 proxy_buffering on; → 改为 proxy_buffering off;,避免大文件堆积内存
- 延长超时:proxy_connect_timeout / proxy_send_timeout / proxy_read_timeout 建议 ≥300s
- 放宽上传限制:client_max_body_size 10G;(按业务设)
- 启用连接池:upstream 内加 keepalive 32;,减少 TCP 开销
常见问题与替代建议
ip_hash 不是万能解:
- 单点故障:某台 server 宕机,对应 IP 段用户全部掉会话,需配合健康检查 + 应用层自动重登录
- 局域网热点:整个 192.168.1.0/24 子网用户全压一台机器,负载严重倾斜
- 想支持权重又想要粘性?改用 hash $remote_addr consistent;,它兼容 weight 且扩缩容影响更小
- 真正绑定的是登录态而非 IP?优先考虑 hash $cookie_jsessionid consistent;,抗 NAT 和代理干扰更强


















