Nginx通过limit_req、limit_conn、map等指令实现请求级QoS控制:支持按API key/IP/用户等级限速、burst/nodelay突发处理、动态分级限流、并发连接控制及请求拦截降级。

在 Nginx 中实现请求级别的 QoS(Quality of Service)控制,核心是利用其内置模块对单个请求进行速率限制、并发控制、优先级调度和响应干预。这不是靠外部组件,而是通过 limit_req、limit_conn、map + limit_req_zone、以及配合 if / return / error_page 等指令完成的精细化控制。
基于请求速率的限流(per-request rate limiting)
使用 limit_req_zone 定义共享内存区域,按特定键(如 $binary_remote_addr、$http_x_api_key、$uri)统计请求频率;再用 limit_req 应用该规则到 location 或 server 块中。关键是设置好 burst 和 nodelay 参数:burst 允许突发请求数,nodelay 决定是否立即拒绝超额请求还是排队等待。
- 示例:对每个 API key 限速 100 r/s,允许最多 20 个请求排队,超时 1 秒后丢弃
limit_req_zone $http_x_api_key zone=api_limit:10m rate=100r/s;limit_req zone=api_limit burst=20 nodelay;- 配合
limit_req_status 429统一返回 429 状态码
按请求特征动态分级限流
借助 map 指令将请求属性(如 header、query string、cookie)映射为不同限流策略标识,再结合多个 limit_req_zone 实现差异化控制。例如:免费用户限 10 r/s,付费用户限 100 r/s,健康检查路径不限流。
- 先定义 map 变量:
map $http_x_user_tier $limit_key { default ""; "premium" "premium"; "free" "free"; } - 分别创建 zone:
limit_req_zone $limit_key zone=free:10m rate=10r/s;和limit_req_zone $limit_key zone=premium:10m rate=100r/s; - 在 location 中用 if 判断并应用对应 zone:
if ($limit_key = "free") { limit_req zone=free burst=5; }
请求级并发连接数控制
虽然 limit_conn 通常用于连接数限制,但可通过绑定到 $binary_remote_addr 或 $http_x_request_id(需客户端配合传递唯一 ID),近似实现“每请求并发”效果。更准确的做法是结合 upstream 的 max_conns 和 proxy_buffering 控制后端实际并发压力。
- 对单个客户端 IP 限制最多 5 个并发连接:
limit_conn_zone $binary_remote_addr zone=addr:10m;+limit_conn addr 5; - 若需按请求 ID 控制(如长轮询或 WebSocket 升级请求),可提取
$http_x_request_id并构造 zone,但注意该 header 需由上游服务或网关统一注入 - 配合
limit_conn_status 429和自定义 error_page 提供结构化错误响应
请求拦截与降级响应
QoS 不只是限流,还包括主动拒绝低优先级请求、返回缓存兜底内容或重定向到降级服务。Nginx 可通过 if + return、error_page + proxy_pass 实现轻量级请求治理。
- 根据请求头判断是否为调试流量,直接返回 200 + 简单 JSON:
if ($http_x_debug = "true") { return 200 '{"status":"ok","qos":"debug"}'; } - 当后端不可用时,用
error_page 502 503 504 = @fallback转向本地静态响应或备用 upstream - 对特定路径(如 /v1/expensive)添加额外校验:
if ($request_method !~ ^(GET|HEAD)$) { limit_req zone=write_limit burst=3; }


















