Nginx - nodelay 选项在限制请求时有什么作用?

Xeo*_*oss 12 nginx rate-limiting

使用 nginx HttpLimitReq模块可以通过 IP 限制请求。但是,我不明白“nodelay”选项的作用。

如果不需要限制突发延迟内的超额请求,则应使用 nodelay

limit_req   zone=one  burst=5  nodelay;
Run Code Online (Sandbox Code Playgroud)

小智 12

TL;DR:如果您想在不限制请求之间允许的间距的情况下施加速率限制,则 nodelay 选项很有用。

我很难消化其他答案,然后我发现了来自 Nginx 的新文档,其中包含回答这个问题的示例:https : //www.nginx.com/blog/rate-limiting-nginx/

这是相关的部分。鉴于:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

location /login/ {
  limit_req zone=mylimit burst=20;
  ...
}
Run Code Online (Sandbox Code Playgroud)

突发参数定义了客户端可以发出多少请求超过区域指定的速率(对于我们的示例 mylimit 区域,速率限制为每秒 10 个请求,或每 100 毫秒 1 个)。在前一个请求之后 100 毫秒内到达的请求被放入队列,这里我们将队列大小设置为 20。

这意味着如果 21 个请求同时来自给定的 IP 地址,NGINX 会立即将第一个请求转发到上游服务器组,并将剩余的 20 个放入队列中。然后它每 100 毫秒转发一个排队的请求,并且仅当传入的请求使排队的请求数超过 20 时才向客户端返回 503。

如果添加 nodelay:

location /login/ {
  limit_req zone=mylimit burst=20 nodelay;
  ...
}
Run Code Online (Sandbox Code Playgroud)

使用 nodelay 参数,NGINX 仍然根据突发参数在队列中分配时隙并强加配置的速率限制,但不是通过间隔转发排队请求。相反,当一个请求“太快”到达时,只要队列中有一个可用的插槽,NGINX 就会立即转发它。它将该插槽标记为“已占用”,并且在适当的时间过去之前(在我们的示例中为 100 毫秒之后)不会释放它以供另一个请求使用。


cor*_*ump 11

这里的文档有一个解释,听起来像你想知道的:

该指令指定区域(zone)和最大可能的请求突发(burst)。如果速率超过区域中概述的需求,请求将被延迟,以便以给定的速度处理查询

据我了解,突发请求将被延迟(需要更多时间并等到可以提供服务),使用nodelay延迟选项不使用延迟,并以 503 错误拒绝多余的请求。

这篇博客文章( archive.org ) 很好地解释了速率限制如何在 nginx 上工作:

如果你像我一样,你可能想知道爆裂到底意味着什么。诀窍是:将“burst”一词替换为“bucket”,并假设每个用户都获得一个带有 5 个令牌的存储桶。每次超过每秒 1 个请求的速率时,他们都必须支付令牌。一旦他们用完所有令牌,他们就会收到一条 HTTP 503 错误消息,这实际上已成为“退避,伙计!”的标准。

  • 我认为你是不正确的,nginx 手册指出:“过多的请求被延迟,直到它们的数量超过最大突发大小”。请注意,*直到超过最大突发*与您所说的*超过突发*完全不同。您还将 *burst* 与 *excess requests* 混为一谈,我相信 *excess requests* 意味着它高于区域,而它可能仍低于 *最大突发*。 (4认同)

Hen*_*wan 6

我的看法如下:

  1. 将尽快处理请求,直到超过区域速率。区域速率是“平均”,所以如果你的速率是1r/s和突发,10你可以在 10 秒窗口内有 10 个请求。

  2. 超过区域速率后:

    一种。没有nodelay,进一步的请求burst将被延迟。

    湾 使用nodelayburst将尽快处理更多请求。

  3. 在之后burst超过,服务器将直到突发窗口期满返回错误响应。例如,对于 rate1r/s和 burst 10,客户端将需要等待 10 秒才能下一个接受的请求。