用 hash $request_uri consistent 是最直接有效的方式,它使相同 url 请求始终路由至同一后端,避免重复回源和缓存碎片;$request_uri 因含完整路径与查询参数、区分大小写且不自动解码,能精确标识资源逻辑版本,优于 $uri 和 $remote_addr。

用 hash $request_uri consistent 是最直接有效的方式。它让相同 URL 的请求始终打到同一台后端,每台机器只缓存自己负责的资源,避免重复加载和跨节点未命中。
为什么必须用 $request_uri 做哈希键
静态资源(JS、CSS、图片、字体等)的完整路径 + 查询参数具有强唯一性和稳定性。用 $request_uri 而不是 $uri 或 $remote_addr,关键在于:
- 包含全部查询参数,比如
/static/app.js?v=2.3.0和/static/app.js?v=2.3.1会被视为两个不同资源,各自固定映射,不会混用缓存 - 不依赖客户端 IP,规避 NAT、CDN 回源带来的哈希漂移问题
-
$uri会丢弃查询参数,$host无法区分同域名下不同资源,都容易导致缓存错乱
Nginx 原生配置要点
无需第三方模块,Nginx 1.7.2+ 已原生支持,但语法必须严格:
- 写法只能是:
hash $request_uri consistent;(注意空格、分号,不能换行或加注释) - upstream 中每个
server行只写地址和端口,例如:server 10.0.2.5:8080; - 禁用
weight、backup、max_fails等指令——它们在一致性哈希模式下不生效,还可能触发配置校验失败
应对热点与扩容的实际优化
纯哈希在百万级集群中可能面临局部倾斜或扩缩容抖动,建议叠加两层控制:
- 对高频 URI(如
/item/123456)做路径归一化:用map指令提取前缀(如/item/* → /item/),再哈希,把同类请求分散到更多节点 - 节点扩容时,启用
consistent后,仅影响新增节点顺时针邻近的一小段 URI 区间,90%+ 请求不受干扰 - 配合
proxy_cache_valid和open_file_cache,提升 Nginx 进程级缓存复用率,进一步降低上游压力











