← 返回题目列表

Nginx 如何实现限流?

高频 中等 第 7 / 25 题 更新于 2026/07/28
Nginx限流漏桶limit_req

简化版

Nginx 主要用两个模块限流:limit_req(请求速率限流)——基于漏桶算法,限制每秒请求数(QPS),超出速率的请求被延迟处理或拒绝,可用 burst 允许一定突发;limit_conn(并发连接数限流)——限制同一个 key(如同一 IP)的并发连接数。两者都通过先定义一个共享内存 zone 记录状态,再在 location 里应用。核心是保护后端不被突发流量或恶意请求打垮。

详细版

① 请求速率限流 limit_req(漏桶):

http {
    # 定义限流规则:按客户端 IP,速率 10 请求/秒,共享内存 10MB
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;

    server {
        location /api/ {
            # 应用限流;burst=20 允许突发 20 个排队,nodelay 不延迟立即处理突发
            limit_req zone=req_limit burst=20 nodelay;
            proxy_pass http://backend;
        }
    }
}

② 并发连接限流 limit_conn

http {
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
    server {
        location /download/ {
            limit_conn conn_limit 3;    # 每个 IP 最多 3 个并发连接
        }
    }
}
  • rate=10r/s:每秒放行 10 个请求(漏桶匀速漏水)。
  • burst=20:允许 20 个请求的突发缓冲(桶容量),超出直接拒绝(返回 503)。
  • nodelay:突发的请求立即处理而非排队延迟(配合 burst 更实用)。
  • limit_conn:限制并发连接数,适合下载、长连接场景。

完整版教学

一、为什么要在 Nginx 层限流

Nginx 是流量入口,在这里限流能把过量请求挡在最外层,保护后端应用和数据库不被突发流量、恶意刷接口、爬虫打垮。相比在应用层限流,Nginx 层限流更靠前、更省资源(超量请求直接被 Nginx 拒绝,根本不占用后端资源)。Nginx 主要提供两种维度的限流:请求速率(QPS)并发连接数

二、limit_req:基于漏桶的请求速率限流

limit_req 限制的是请求的速率(每秒多少个请求),底层是漏桶算法

漏桶算法:想象一个底部有孔的桶,请求像水一样倒进桶里,桶底以恒定速率漏水(放行请求)。

  • rate=10r/s:漏水速率——每秒匀速放行 10 个请求(每 100ms 一个)。
  • 请求来得比漏水快时,多的先在桶里排队;桶满了(超过容量)就溢出——请求被拒绝(返回 503)。

配置分两步:

  1. limit_req_zone 定义规则:按什么 key 限流($binary_remote_addr 是客户端 IP)、共享内存区大小、速率。
  2. limit_req 在 location 里应用这个规则。

三、burst 和 nodelay:处理突发流量

纯漏桶(rate=10r/s)非常严格——超过每秒 10 个就拒绝,但实际流量常有短暂突发(比如某一刻来了 15 个请求,其实系统扛得住)。直接拒绝体验差。用 burstnodelay 优化:

  • burst=20:允许一个容量为 20 的缓冲队列(桶的容量)。超过 rate 速率的请求,只要不超过 burst 数量,就先排队等待(按 rate 速率慢慢放行),而不是立即拒绝。只有连 burst 队列都满了才拒绝。这样能吸收突发。
  • nodelay:如果只配 burst 不配 nodelay,突发请求会被延迟处理(按 rate 慢慢放,用户等待久)。加上 nodelay,突发的请求立即处理(不排队等待),但仍占用 burst 名额——名额在后续时间里按 rate 慢慢释放。burst + nodelay 是实践中最常用的组合,既限了平均速率,又能立即响应突发。

四、limit_conn:并发连接数限流

limit_conn 限制的是同时保持的连接数,而非速率。适合长连接、下载、上传这类场景——比如限制每个 IP 同时只能有 3 个下载连接,防止单个用户开几十个连接占满带宽。

配置同样两步:limit_conn_zone 定义规则(按 IP),limit_conn conn_limit 3 应用(每个 IP 最多 3 个并发连接)。超过的连接被拒绝。

limit_req vs limit_conn

  • limit_req速率(每秒多少请求)——防高频刷接口。
  • limit_conn并发数(同时多少连接)——防单用户占用过多连接资源。 两者常配合使用。

五、限流的 key 与粒度

限流的维度(key) 决定了「按什么来限」,通过 zone 定义时的变量控制:

  • $binary_remote_addr:按客户端 IP 限流(最常用,binary 形式比 $remote_addr 省内存)。
  • $server_name:按域名限流。
  • 自定义变量:如按 URL 参数、请求头里的用户 ID 等限流(更细粒度)。

选对 key 很重要:按 IP 限流对付单机刷接口有效,但如果攻击来自大量不同 IP(分布式),或大量用户在同一 NAT 出口 IP 下,按 IP 就不合适,要结合业务维度。

六、常见误区与追问

考点正确口径
限流目标保护后端、防刷、防突发流量打垮系统
Nginx 手段limit_req 限请求速率,limit_conn 限连接数
算法理解漏桶平滑流量,burst 允许短时排队
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
location /api/ {
  limit_req zone=api burst=20 nodelay;
  proxy_pass http://backend;
}

Nginx 限流要说清维度:按 IP、用户、接口还是全局;维度错了就会误伤或漏防。

  • 误区:限流只要按 IP 就够。 NAT、代理和真实用户共享 IP 会误伤,登录态场景可按用户或 token 限流。
  • 误区:burst 表示无限放行突发流量。 burst 是可排队或瞬时处理的额外请求上限,超过仍会被拒绝。
  • 误区:Nginx 限流能替代业务风控。 Nginx 适合入口流量控制,复杂风控仍要结合用户、设备和业务行为。
  • 追问:limit_req 和 limit_conn 区别? limit_req 控制请求速率,limit_conn 控制并发连接数。
  • 追问:nodelay 有什么影响? 启用后 burst 内请求不排队等待,直接放行但仍受 burst 上限约束。
  • 追问:限流后返回什么? 通常返回 503 或自定义状态码,也可配置错误页和降级响应。

七、加强记忆

Nginx 限流两大模块:limit_req(请求速率)——基于漏桶算法rate=10r/s 匀速放行,用 burst 提供突发缓冲队列(超 rate 的请求排队而非立即拒,满了才拒)、nodelay 让突发请求立即处理(burst+nodelay 最常用),防高频刷接口;limit_conn(并发连接数)——限制同一 key 的并发连接,适合下载/长连接。都是先 xxx_zone 定义规则(key 常用 $binary_remote_addr 按 IP)再在 location 应用。价值是在最前的流量入口挡掉过量请求,保护后端。口诀:limit_req 管速率(漏桶+burst+nodelay)、limit_conn 管并发连接