Nginx的limit_req基于漏桶算法实现限流,依赖limit_req_zone定义区域与速率、limit_req启用并配置burst/nodelay;支持IP、接口路径、用户标识等多维度限流,需合理调优burst、nodelay及内存大小。
用 Nginx 做反向代理时,不加限流就像给后端服务敞开大门——突发流量、恶意扫描、爬虫洪峰都可能直接压垮应用。limit_req 是 Nginx 内置的轻量级限流模块,无需额外组件,配置得当就能有效兜底。
理解 limit_req 的核心机制
limit_req 不是简单统计请求数,而是基于“漏桶算法”实现平滑限流:请求进入桶中,按固定速率漏出(即被放行);桶满则拒绝新请求(返回 503)。关键依赖两个指令:
limit_req_zone
:定义限流区域(key)、内存空间、速率(如 r/s 或 r/m)
limit_req
:在 server 或 location 中启用该区域,并可设置突发容量(burst)和是否延时(nodelay)
基础限流配置示例
以限制单个 IP 每秒最多 10 个请求为例:
}
说明:
-
$binary_remote_addr
比 $remote_addr 更省内存(IPv4 固定 4 字节)
-
burst=20
表示允许最多 20 个请求排队等待(不阻塞,但可能延迟响应)
-
nodelay
表示不排队,超出速率的请求立即 503(适合强实时场景)
按业务维度精细化限流
单一 IP 限流不够灵活,常需结合业务特征:
按接口路径限流
:用 $request_uri 或自定义变量,例如对 /login 接口单独设低速(防爆破)
按用户标识限流
:若 header 中有 X-User-ID,可用
多级限流组合
:先全局 IP 限流兜底,再对关键接口加一层更严策略(嵌套使用不同 zone)
调优与排障要点
上线后需关注三点:
日志里检查
拒绝记录(默认记为 error 级别,可配合 log_format 追踪 key)
burst 值不宜过大,否则失去限流意义;nodelay 要慎用,避免前端重试风暴
内存 zone 大小要合理:10m 约支持 16 万个 IP,高并发需按预估连接数扩容
不复杂但容易忽略。
http {
limit_req_zone $binary_remote_addr zone=ip_limit:10m rate=10r/s;
server {
location /api/ {
proxy_pass http://backend;
limit_req zone=ip_limit burst=20 nodelay;
}
}limit_req_zone $http_x_user_id zone=user_limit:10m rate=5r/slimit_req