关键是对接口路径下同时存在的TCP连接总数进行管控,需用map归一化URI构造限流键,通过limit_conn_zone定义共享内存区,并在location中用limit_conn绑定生效,还可叠加IP维度限流和优化keepalive超时。

要对特定接口做静态连接管控,关键不是限制“每秒请求数”,而是控制该接口路径下**同时存在的 TCP 连接总数**。Nginx 本身不直接识别接口路径,必须借助变量构造唯一键,再通过 limit_conn_zone 定义计数区域,最后在 location 中用 limit_conn 绑定生效。
用 $uri 或自定义 map 构造接口级限流键
接口路径通常稳定、参数少,适合用 URI 作为限流维度,但要注意:
-
$uri不含 query string,适用于路径唯一、参数走 body 或 header 的场景(如/api/report/export); -
$request_uri含完整 URL,若带时间戳、随机数等高频变动参数,会导致 key 爆炸,不推荐; - 更稳妥的做法是用
map显式归一化目标接口:
~^/api/report/ "report_api";
~^/api/export/ "export_api";
~^/v1/metrics "metrics_v1";
default "";
}
这样所有匹配前缀的请求都映射为固定标识,避免因细微路径差异(如尾部斜杠、大小写)产生冗余 key。
定义共享内存区并绑定 location
在 http{} 块中声明 zone,内存大小按接口数量预估:
5MB 内存约支持 16 万个独立键,几十个核心接口完全够用。然后在对应 location 中启用限制:
limit_conn api_conn 8;
limit_conn_status 429;
limit_conn_log_level warn;
proxy_pass http://backend;
}
^~ 前缀确保前缀匹配优先于正则,性能更高;数值 8 表示该接口路径下最多维持 8 个并发 TCP 连接(HTTP/2 单连接多 stream 仍计为 1)。
叠加 IP 维度形成双层防护
仅按接口限流无法防止单个客户端发起多个不同子路径请求打穿配额。建议同步限制单 IP 对该接口的连接数:
- 在
http{}中补充:limit_conn_zone $binary_remote_addr zone=ip_per_api:10m; - 在同个
location内叠加:limit_conn ip_per_api 3;
效果是:任一客户端访问 /api/report/xxx 最多建 3 个连接,所有客户端对该路径总连接数不超过 8 个,兼顾公平性与稳定性。
优化空闲连接释放以提升配额利用率
keepalive 连接长期空闲会持续占用配额。建议显式缩短空闲时长:
keepalive_timeout 12;配合 limit_conn 使用时,12 秒比默认 60 秒更合理——既减少 idle 连接堆积,又避免频繁重连影响体验。若后端支持 HTTP/2,还可进一步降低该值,因复用效率更高。










