直接用 hash $request_uri consistent 可实现 URL 级一致性路由,确保相同 URI 总转发至同一后端,提升缓存命中率;$request_uri 含完整路径与原始查询参数,区分大小写且不自动解码,能精确标识逻辑请求,优于 $uri(无参数)、$args(无路径)、$remote_addr(NAT 下失效);配置须满足:必加 consistent、禁用 weight、规范 URI 编码。

直接用 hash $request_uri consistent 就能实现集群中缓存命中的一致性路由,核心是让相同 URL 总落到同一台后端,避免重复回源和缓存碎片。
为什么选 $request_uri 作为哈希键
$request_uri 包含完整路径与原始查询参数(如 /api/goods?id=1001&v=2),区分大小写、不自动解码,能精确代表一次逻辑请求。相比其他变量:
-
$uri丢弃 query string,/goods/1和/goods/1?from=app会被分到不同节点,缓存无法共享; -
$args只有参数部分,缺少路径信息,无法区分/user和/order这类不同接口; -
$remote_addr按 IP 哈希,在 NAT 或多设备场景下易打散,且不保证资源级复用。
基础 upstream 配置要点
必须满足三个硬性条件,否则一致性效果失效:
- 指令必须写成
hash $request_uri consistent;,consistent参数不可省略; - 所有
server行不能带weight=,权重会破坏哈希分布逻辑; - 确保前端请求 URI 编码规范,避免未编码空格或中文导致 400;必要时在
server块加underscores_in_headers on并统一编码标准。
配合后端缓存策略生效
仅靠 Nginx 路由不够,后端行为必须对齐:
- 各后端服务生成的缓存 Key 规则要一致,例如都 strip 掉
utm_*类追踪参数,否则同一$request_uri在不同机器存的是不同内容; - 推荐使用共享缓存(如 Redis 集群)而非纯本地内存缓存,避免单机容量瓶颈;
- Nginx 层开启
proxy_cache_lock on;,防止缓存未命中时多个相同请求并发回源。
Kubernetes Ingress 场景配置
在 Nginx Ingress Controller 中,无需修改 upstream,直接通过注解启用:
- 1.23+ 版本:添加
nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"; - 确保 Ingress Controller 使用的 Nginx 版本 ≥ 1.7.2(原生支持
hash ... consistent); - 避免同时设置多个 hash 注解,否则可能被覆盖。

















