nginx可通过hash指令配合变量实现基于url路径、请求头/cookie、查询参数的自定义哈希路由,需使用map预处理变量并启用consistent参数保障一致性。

Nginx 本身不支持直接对任意请求字段(如 URL 路径、Header、参数)做自定义哈希键值的原生配置,但可通过 hash 指令配合变量实现精准路由,前提是使用 ngx_http_upstream_hash_module(Nginx 1.7.2+ 默认内置,无需额外编译)。
关键点在于:hash 的输入必须是 Nginx 变量($variable),且该变量需在请求处理早期可稳定获取。下面分三类实用场景说明配置方法和注意事项:
基于请求路径哈希(URL 精准路由)
适合按资源路径做一致性分发,比如 /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;
}
说明:
-
$request_uri 包含路径+查询参数(如
/user?id=100),若只需路径部分,改用$uri(不含 query) - consistent 参数启用一致性哈希,比默认普通哈希更抗节点变动抖动
- 注意:URI 中含动态参数(如时间戳、随机数)会导致哈希失效,建议前置用
map清洗
基于请求头或 Cookie 自定义键
当需要按用户 ID、设备标识等业务字段路由时,可提取 Header 或 Cookie 中的值构造哈希键。
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
例如从 X-User-ID 头取值:
map $http_x_user_id $hash_key {
"" "anonymous";
default $http_x_user_id;
}
<p>upstream backend_by_user {
hash $hash_key consistent;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}</p>
说明:
-
map块用于安全转换:避免空值导致哈希异常,统一 fallback 到anonymous -
$http_x_user_id是 Nginx 自动将 Header 名转为小写下划线格式的变量 - 若字段在 Cookie 中(如
uid=abc123),可用$cookie_uid直接引用
基于查询参数提取哈希键(如 tenant_id)
多租户系统中常需按 ?tenant_id=org-a 将同租户流量固定到同一组后端。
配置方式:
map $args $tenant_hash {
~tenant_id=([^&]+) $1;
default "default_tenant";
}
<p>upstream backend_by_tenant {
hash $tenant_hash consistent;
server 192.168.1.20:8080;
server 192.168.1.21:8080;
}</p>
说明:
-
~tenant_id=([^&]+)是正则匹配,捕获tenant_id后第一个&前的值 - 未匹配时 fallback 到
default_tenant,确保所有请求都有确定哈希源 - 注意:正则匹配发生在 rewrite 阶段,需确保
args未被重写覆盖
不复杂但容易忽略:所有自定义 hash 键必须在 upstream 块外预先定义(如 map),且变量值不能含空格或不可见字符;上线前务必用 nginx -t 校验语法,并用真实请求验证哈希分布是否均匀。










