可突破IP限流限制,通过map构建语义化key实现业务粒度限流:如按导出路径、用户等级、租户+模块组合、异常登录状态等差异化控制,并需平衡key精细度与内存占用。

直接用 limit_req_zone 配合自定义变量,就能突破“只按 IP 限流”的限制,把控制粒度落到真实业务场景里——比如区分 VIP 用户和普通用户、限制导出接口调用频次、拦截异常登录行为等。
用 map 构建语义化 key
Nginx 不支持从请求体或复杂逻辑中直接取值,但可通过 map 指令,基于已有字段(如 header、cookie、URI 参数)映射出可读性强、带业务含义的变量,作为 limit_req_zone 的 $key:
- 识别高风险路径:
map $request_uri $is_export { ~^/api/v1/export 1; default 0; }
再定义限流区域:limit_req_zone $is_export zone=export_limit:5m rate=2r/m;——只有导出请求被统计,其他完全不受影响 - 提取业务 ID:
map $arg_bid $bid { "" "unknown"; default $arg_bid; }
避免空值导致 key 冲突,同时便于日志归因
按用户身份或租户分层限流
若后端已透传用户等级或租户标识,可分别建 zone 实现差异化策略:
- 对 VIP 用户宽松、对游客严格:
limit_req_zone $http_x_user_rank zone=rank_limit:10m rate=5r/s;limit_req_zone $http_x_user_id zone=user_limit:20m rate=1r/s; - 组合多级标识(如租户+模块):
set $biz_key "$http_x_tenant_id:$http_x_module";limit_req_zone $biz_key zone=tenant_module_limit:20m rate=50r/s;
冒号拼接便于后续日志解析和监控下钻
响应业务状态做动态限流
限流策略需随业务信号实时调整。纯 Nginx 场景下可用“状态上报 + map 判断”间接实现:
- 前端或网关检测到异常(如 1 分钟内连续 3 次 401),写入带时间戳的 cookie:
abnormal=1678901234 - 用 map 判断该 cookie 是否存在且未过期,生成特殊 key:
map $http_cookie $abnormal_key { ~abnormal=(\d+) $1; default ""; } - 为该 key 单独设极严限速:
limit_req_zone $abnormal_key zone=abnormal_limit:2m rate=0.1r/s;
注意内存与 key 粒度的平衡
key 越精细,内存占用越高,需结合实际规模预估:
-
$binary_remote_addr:IPv4 固定 4 字节,1MB ≈ 支持 1.6 万个 IP - 字符串类 key(如
$http_x_user_id):长度不可控,建议 zone size 预留余量(例如 10MB 约支持 16 万个唯一 key) - 避免直接用
$request_uri做 key:URI 高熵、变化多,极易撑爆内存










