可通过nginx的limit_req_zone指令结合x-user-id或x-tenant-id等自定义请求头实现多租户限速,关键是以$http_x_user_id等变量为key定义限速区域,并用map过滤空值、支持租户与用户两级限速,且需确保头字段由可信上游透传。

可以通过 limit_req_zone 指令配合 Nginx 的自定义请求头(如 X-User-ID 或 X-Tenant-ID)来实现基于用户身份的多租户限速,关键在于让限速键(key)动态提取并区分不同租户或用户,而非仅依赖 IP。
1. 定义基于自定义头字段的限速区域
使用 $http_x_user_id 或 $http_x_tenant_id 作为限速 key,确保每个用户/租户独立计数:
limit_req_zone $http_x_user_id zone=user_limit:10m rate=5r/s; limit_req_zone $http_x_tenant_id zone=tenant_limit:10m rate=100r/m;
说明:
-
$http_x_user_id自动映射请求头X-User-ID的值(大小写不敏感,Nginx 内部转为小写) - 若请求未携带该头,变量值为空字符串,所有无头请求将被归入同一桶(可加条件过滤,见下文)
- 建议搭配
burst和nodelay控制突发行为,例如:limit_req zone=user_limit burst=10 nodelay;
2. 过滤无效或缺失头字段的请求
避免空 key 导致租户间“撞桶”,用 map 构建安全 key:
map $http_x_user_id $safe_user_key {
"" "invalid";
default $http_x_user_id;
}
limit_req_zone $safe_user_key zone=user_safe:10m rate=5r/s;
这样所有缺失 X-User-ID 的请求统一走 "invalid" 桶,便于单独限速或后续日志识别。
3. 多级限速:租户 + 用户双重控制
先限制租户总频次,再限制其下用户个体频次,需两个 zone 并按顺序应用:
limit_req zone=tenant_limit burst=50 nodelay; limit_req zone=user_safe burst=5 nodelay;
注意执行顺序:Nginx 按配置出现顺序依次检查,前一个拒绝则不再执行后续限速。建议把租户级放前面,防止单个恶意用户耗尽租户额度。
4. 配合 auth_request 或 JWT 解析实现可信身份提取
若用户 ID 存于 JWT token 中,不能直接用 $http_authorization,需借助 auth_request 模块或第三方模块(如 nginx-jwt)解析后注入头字段:
- 在认证子请求中解析 token,设置
X-User-ID头返回给主请求 - 或使用 OpenResty + Lua,在
access_by_lua_block中解签并 set $user_id,再用于 limit_req_zone - 纯 Nginx 场景下,务必确保上游服务(如 API 网关)已校验并透传可信头字段,禁用客户端伪造
不复杂但容易忽略:限速效果依赖头字段的稳定性和可信链路,务必在反向代理最外层统一注入/校验,避免绕过。










