在 nginx 中配置 ip_hash 实现会话保持,需要在 upstream 块中直接添加 ip_hash 指令。该机制基于客户端 ip 地址的哈希值将请求固定分发到同一台后端服务器,从而确保来自同一 ip 的请求始终由同一实例处理。需要注意的是,如果多个用户共享同一个出口 ip(如公司 nat 或移动网络),他们会被映射到同一台服务器,这可能导致负载不均或会话冲突。

如何定义包含 ip_hash 的 upstream 块
要在 Nginx 中启用此功能,必须在 http 上下文中定义一个 upstream 模块,并在其中加入 ip_hash 关键字。接着,在该块内列出所有可用的后端服务器节点。当 Nginx 接收到请求时,它会提取客户端的 IP 地址,计算其哈希值,并根据该值选择对应的服务器。这种配置方式简单直接,无需额外的 Cookie 或 Header 支持。

upstream backend_app {
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080 down;
}
上述配置中,server 192.168.1.12:8080 down; 表示该节点当前被标记为不可用,不参与哈希计算和请求分发。实际运行时,Nginx 仅对前两个活跃节点进行哈希映射。客户端 IP 10.0.0.5 的请求将被稳定路由至其中一个活跃节点,直到该节点宕机或配置变更。
ip_hash 在不同客户端 IP 下的路由行为
ip_hash 的核心逻辑是确定性路由,即相同的输入 IP 永远产生相同的输出服务器。这意味着一旦映射建立,只要后端服务器列表不变,用户的会话状态就能在服务端保持一致。然而,若后端服务器发生增减,哈希环会重新计算,导致部分用户的请求跳转到新服务器,造成短暂的会话丢失。因此,在生产环境中调整服务器数量时需谨慎,最好配合滚动重启或灰度发布策略。

# 模拟测试:查看不同 IP 的哈希分布 # 假设使用默认 Jenkins 哈希算法 # IP: 192.168.1.100 -> Server A # IP: 192.168.1.101 -> Server B # IP: 192.168.1.102 -> Server A
通过观察日志或监控工具,可以验证特定 IP 是否始终访问同一后端。例如,IP 192.168.1.100 的所有请求都指向 Server A,而 192.168.1.101 指向 Server B。这种一致性依赖于哈希算法的稳定性,Nginx 内部使用固定的算法确保长期映射不变。若需自定义哈希来源,可结合 hash 指令替代默认的 ip_hash,但标准场景下直接使用 ip_hash 即可满足大多数会话保持需求。
当后端服务器宕机时 ip_hash 如何处理故障转移
在 ip_hash 模式下,如果某台后端服务器宕机,Nginx 会自动将该服务器从哈希池中移除,并将原本分配给它的请求重新哈希到其他存活节点。这一过程是动态的,无需手动干预。但需要注意的是,原属于宕机服务器的用户会话将失效,因为他们的请求现在被转发到了不同的服务器实例。为避免数据不一致,建议在后端应用层实现会话复制或持久化存储,如使用 Redis 集中管理 Session 数据。


















