核心是用map将业务语义编译为限流key,实现租户、接口、用户等维度的静态精准管控;需降维防爆、分zone隔离、白名单跳过、日志可观测。

用 limit_req_zone 结合自定义变量做静态高维度管控,核心是把业务语义“编译”进限流 key,让每个桶代表一类真实业务实体(比如某个租户、某类接口、某级用户),而不是原始 IP 或泛化路径。这种管控不依赖运行时计算,配置即生效,内存可控、策略稳定,适合大规模生产环境。
用 map 构建带业务含义的 key
直接用 $request_uri 或 $args 做 key 容易爆炸,必须先降维。map 是最轻量、最静态的方式:
- 匹配导出类接口:
map $request_uri $is_export { ~^/api/.*/export 1; default 0; },所有导出请求归为同一 key “1” - 识别租户来源:
map $http_x_tenant_id $tenant_key { "" "unknown"; default $http_x_tenant_id; },空值兜底,避免 key 泛化 - 组合多维标识:
set $biz_key "$tenant_key:$http_x_api_group";(需在 rewrite 阶段),形成acme:report这样的可读 key
按业务重要性分设 zone,隔离资源
不堆一个大 zone,而是按粒度、存活期、风险等级拆开,让内存各尽其用:
-
limit_req_zone $is_export zone=export_rate:2m rate=3r/m;:导出接口极低频,2MB 内存够用,且 key 只有两个值(0/1) -
limit_req_zone $tenant_key zone=tenant_qps:10m rate=50r/s;:租户数可控(如 2000 个),10MB 支持约 16 万 key,冗余充足 -
limit_req_zone $http_x_user_agent zone=ua_flood:1m rate=1r/s;:只防 UA 轮换爆破,key 数量极少,长期驻留也不占资源
静态兜底与白名单机制
真正高可用的静态管控,必须明确“哪些不控”,而非只写“哪些要控”:
- 用 map 将可信源映射为空字符串:
map $remote_addr $skip_limit { ~^10\. ""; ~^172\.1[6-9] ""; default $binary_remote_addr; },CDN 回源、内网调用、健康检查全部跳过计数 - 对未登录用户或无效标识,统一归入
"guest"或"invalid"这类固定 key,单独配宽松策略(如rate=10r/s),不污染主 zone - 禁用客户端伪造头:
underscores_in_headers off;,并配合if ($http_x_user_id) { ... }清洗,确保 key 来源可信
日志与可观测性设计
静态策略必须可验证、可归因,否则就是黑盒:
- 在 log_format 中显式记录 key 值:
tenant="$tenant_key" biz_key="$biz_key" limit_status="$limit_req_status" - 开启限速日志:
limit_req_log_level warn;,error.log 中出现limiting requests即表示命中,结合 key 字段快速定位是哪个租户或哪类接口触发 - 监控
nginx_http_limit_req_dropped_total(若启用 Prometheus Exporter),配合 key 标签聚合,发现异常突增时能秒级下钻到业务维度

















