Nginx可通过hash指令配合变量实现基于URL路径、请求头/Cookie、查询参数的自定义哈希路由,需使用map预处理变量并启用consistent参数保障一致性。
Nginx 本身不支持直接对任意请求字段(如 URL 路径、Header、参数)做自定义哈希键值的原生配置,但可通过 hash 指令配合变量实现精准路由,前提是使用 ngx_http_upstream_hash_module(Nginx 1.7.2+ 默认内置,无需额外编译)。
关键点在于:hash 的输入必须是 Nginx 变量($variable),且该变量需在请求处理早期可稳定获取。下面分三类实用场景说明配置方法和注意事项:
适合按资源路径做一致性分发,比如 /api/user/123 → 固定到某台后端,提升缓存命中率或避免跨节点状态冲突。
配置示例:
upstream backend_by_path {hash $request_uri consistent;# 使用完整 URI 哈希,加 consistent 减少节点增减时的重映射server 192.168.1.10:8080;server 192.168.1.11:8080;server 192.168.1.12:8080;}
说明:
/user?id=100),若只需路径部分,改用 $uri(不含 query)map 清洗当需要按用户 ID、设备标识等业务字段路由时,可提取 Header 或 Cookie 中的值构造哈希键。
例如从 X-User-ID 头取值:
map $http_x_user_id $hash_key {"""anonymous";default $http_x_user_id;}upstream backend_by_user { hash $hash_key consistent; server 192.168.1.10:8080; server 192.168.1.11:8080; }
说明:
map 块用于安全转换:避免空值导致哈希异常,统一 fallback 到 anonymous
$http_x_user_id 是 Nginx 自动将 Header 名转为小写下划线格式的变量uid=abc123),可用 $cookie_uid 直接引用多租户系统中常需按 ?tenant_id=org-a 将同租户流量固定到同一组后端。
配置方式:
map $args $tenant_hash {~tenant_id=([^&]+) $1;default "default_tenant";}upstream backend_by_tenant { hash $tenant_hash consistent; server 192.168.1.20:8080; server 192.168.1.21:8080; }
说明:
~tenant_id=([^&]+) 是正则匹配,捕获 tenant_id 后第一个 & 前的值default_tenant,确保所有请求都有确定哈希源args 未被重写覆盖不复杂但容易忽略:所有自定义 hash 键必须在 upstream 块外预先定义(如 map),且变量值不能含空格或不可见字符;上线前务必用 nginx -t 校验语法,并用真实请求验证哈希分布是否均匀。