可通过limit_req_zone和map指令实现基于API Key的多租户独立限速:先用map从X-API-Key头提取并清洗租户标识为$api_key,再以该变量定义限速区域,确保空值非法值映射为"-"避免绕过或内存耗尽,最后在location中启用限速、透传租户信息并校验合法性。

可以通过 limit_req_zone 定义基于 API Key 的限速区域,并配合 map 指令从自定义请求头(如 X-API-Key)提取租户标识,实现多租户独立限速。关键在于让每个租户的 API Key 映射为唯一、稳定的限速键,且避免空值或非法值干扰限速逻辑。
定义基于 API Key 的限速区域
使用 $api_key 变量作为限速键,需确保它已通过 map 提前解析并标准化:
- 在
http块中声明限速区域,例如每秒最多 10 个请求,突发容量 20:
limit_req_zone $api_key zone=apikey_limit:10m rate=10r/s;
其中 10m 是共享内存大小,足够存储数万个不同 API Key 的计数器;rate 和 burst 参数按租户等级差异化配置时,可搭配多个 zone 使用。
用 map 从自定义头提取并清洗 API Key
map 指令用于安全地从 X-API-Key 头中提取值,并处理缺失、空、过长或含非法字符的情况:
- 默认将空值、空白、超长(如 >64 字符)或含控制字符的值映射为特殊标记(如
"-"),使其不参与有效限速; - 合法 API Key 经 trim 和长度截断后直接使用,保证键稳定性:
map $http_x_api_key $api_key {
"" "-";
"~^\s*$" "-";
"~^[a-zA-Z0-9_\-]{8,64}$" $http_x_api_key;
default "-";
}
这样既防止空头绕过限速,又避免恶意构造超长 Key 耗尽共享内存。
在 location 中启用限速并透传租户信息
在反向代理的 location 块中调用限速,并可选地将租户标识注入后端请求头,便于日志或鉴权联动:
- 使用
limit_req引用前面定义的 zone,设置burst和nodelay策略; - 添加
proxy_set_header X-Tenant-ID $api_key,供上游服务识别租户; - 对非法 Key 返回 400,避免无效请求进入限速或后端:
location /api/ {
limit_req zone=apikey_limit burst=20 nodelay;
if ($api_key = "-") {
return 400 "Invalid or missing X-API-Key";
}
proxy_pass https://backend;
proxy_set_header X-Tenant-ID $api_key;
}
支持多级租户策略(可选进阶)
若需按租户类型(免费/付费)应用不同速率,可扩展 map 输出多个变量,再分别定义 zone:
- 例如用
$api_tier区分free/pro,再定义zone=free_limit和zone=pro_limit; - 在
limit_req中用zone=$tier_zone动态选择(需 Nginx ≥ 1.13.10); - 或直接在
map中拼接 tier + key,如"pro_$http_x_api_key",实现隔离更强的键空间。
这种方式无需修改代码即可通过配置调整各租户配额,适合 SaaS 类反向代理网关场景。

















