可通过limit_req_zone配合map指令提取并归一化X-API-Key实现多租户独立限速,每个合法Key独享100r/s,burst=200支持突发,需后端鉴权兜底并监控zone命中情况。

可以通过 limit_req_zone 指令配合自定义请求头(如 X-API-Key)提取租户标识,实现以 API Key 为单位的独立限速,从而支撑多租户场景下的精细化流量控制。
配置 limit_req_zone 提取 API Key 作为 key
Nginx 不支持直接对请求头做复杂处理,但可通过 map 指令预处理,将可信的 API Key 映射为标准化值(如去除空格、转小写、过滤非法字符),再用于限速维度:
- 在
http块中定义map,安全地提取并归一化 API Key:
map $http_x_api_key $api_key_normalized {
"" "";
~^(?<key>[a-zA-Z0-9_\-]{16,64})$ $key;
default "";
}
该规则只接受长度 16–64、仅含字母数字与常见分隔符的 Key,其余情况归为空字符串(即不参与限速)。
- 基于归一化后的 Key 定义限速区域:
limit_req_zone $api_key_normalized zone=api_per_key:10m rate=100r/s;
每个合法 API Key 独享 100 QPS,共享内存区大小为 10MB(可支撑约 16 万个不同 Key)。
在 location 中启用限速并设置合理行为
在对应 API 路由中引用该 zone,并配置拒绝策略与突发容量:
location /api/ {
limit_req zone=api_per_key burst=200 nodelay;
proxy_pass http://backend;
}
-
burst=200允许短时突发(如冷启动或重试),避免瞬时抖动误触发限流 -
nodelay表示突发请求不延迟,超出部分直接 503;若需平滑削峰,可去掉该参数,让 Nginx 匀速释放 burst 请求 - 建议搭配
limit_req_status 429显式返回 429 Too Many Requests,便于客户端识别限速状态
增强安全性:校验与兜底机制
仅靠 header 限速存在绕过风险,需叠加基础防护:
- API Key 必须经后端鉴权确认有效性,Nginx 层的限速仅作前置保护,不替代业务校验
- 对缺失或无效 API Key 的请求,应统一拒绝(可用
if ($api_key_normalized = "") { return 400; }),防止空 key 占用限速槽位 - 为防租户滥用(如一个 Key 被多个客户端共享),可额外按 IP 或 User-Agent 组合限速:
limit_req_zone "$api_key_normalized|$binary_remote_addr" zone=api_ip_per_key:10m rate=5r/s;
监控与调试技巧
限速生效需验证是否真正按 Key 区分计数:
- 开启 Nginx 日志变量
$limit和$limit_rate,记录当前匹配的限速 zone 名称及速率 - 使用
stub_status或nginx-module-vts查看 zone 实时命中数、当前请求数,确认不同 Key 是否各自计数 - 测试时用 curl 发送带不同 X-API-Key 的请求,观察响应头中的
X-RateLimit-Limit和X-RateLimit-Remaining(需配合 echo 模块或 Lua 注入)

















