Windows下Nginx原生hash不支持一致性哈希,仅支持普通哈希取模;增减后端节点会导致大部分key重映射。可行方案为使用OpenResty(含Lua实现一致性哈希)或改用Nginx Plus(但无Windows版)。

Windows 下 Nginx 的 upstream hash 指令本身不支持一致性哈希(consistent hashing),这是关键前提。Nginx 官方版(包括 Windows 编译版)的 hash 指令仅支持普通哈希 + 轮询兜底(hash $key consistent; 是不存在的语法),真正的 consistent hashing 需要第三方模块。
官方 hash 指令的实际行为(非一致性)
Nginx 原生 hash 指令工作方式是:
- 对指定变量(如
$remote_addr、$request_uri)计算 CRC32 哈希值 - 对该哈希值对后端服务器数量取模,决定转发目标
- 当 upstream 中增减服务器时,绝大多数 key 的映射关系会改变 → 不具备一致性
例如:3 台 server 时,key A 映射到 server2;删掉 server1 后只剩 2 台,key A 很可能映射到 server1 —— 这正是传统哈希的“雪崩”问题。
Windows 下实现一致性哈希的可行方案
在 Windows 环境中,有且仅有以下两种实用路径:
-
使用 OpenResty(推荐):OpenResty 是基于 Nginx + Lua 的发行版,Windows 官方提供预编译包(openresty.org/download)。它内置
balancer_by_lua*和resty-balancer库,可轻松实现一致性哈希逻辑。示例 Lua 代码片段:lua_shared_dict consistent_hash_dict 10m; upstream backend { server 0.0.0.0:1; # 占位,实际由 Lua 分发 } <p>location / { balancer_by_lua_block { local balancer = require "ngx.balancer" local resty_hash = require "resty.hash" local hash = resty_hash:new() local key = ngx.var.remote_addr .. ngx.var.uri local servers = { "127.0.0.1:8081", "127.0.0.1:8082", "127.0.0.1:8083" } local node = servers[hash:hash(key, #servers) + 1] local host, port = string.match(node, "(.<em>):(.</em>)") local ok, err = balancer.set_current_peer(host, tonumber(port)) if not ok then ngx.log(ngx.ERR, "failed to set peer: ", err) end } proxy_pass <a href="https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e">https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e</a>; }</p> -
改用 nginx-plus(不推荐 Windows):Nginx Plus 商业版支持
hash $key consistent;语法,但官方不提供 Windows 版本,仅支持 Linux/macOS。Windows 下无法使用。
替代思路:用 sticky session 规避一致性需求
若目标是会话保持(如用户登录态),而非严格 key 分布,可考虑更轻量的方案:
-
ip_hash:按客户端 IP 哈希,简单稳定,适合内网或 IP 较固定的场景 -
cookie(需第三方模块):如nginx-sticky-module-ng,但该模块无官方 Windows 支持,需自行编译(难度高、维护成本大) - 应用层控制:在业务代码中生成 token 并路由,Nginx 仅做透明代理
验证与调试建议
无论采用哪种方式,务必验证一致性效果:
- 写个简单脚本,模拟 1000 个不同 key,记录每轮(3/4/5 台 server)的分发结果
- 对比增减节点前后,相同 key 是否始终落在同一台 server 上
- 开启 Nginx
error_log debug;,配合log_subrequest on;查看真实转发目标
Windows 下路径、权限、防火墙也常导致 upstream 不可达,先确保基础代理正常再优化哈希逻辑。










