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


11

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

如果在限制突发延迟内没有多余的请求,则应使用nodelay

limit_req   zone=one  burst=5  nodelay;

Answers:


11

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

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

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

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

如果您像我,您可能想知道爆炸的真正含义是什么。这是窍门:用“ bucket”代替“ burst”一词,并假设每个用户都获得了一个带有5个令牌的存储桶。每当它们超过每秒1个请求的速率时,就必须支付令牌。一旦他们用完所有令牌,就会收到一条HTTP 503错误消息,该消息实际上已成为“退后,伙计!”的标准。


4
我认为您是错误的,nginx手册指出:“过多的请求被延迟,直到它们的数量超过最大突发大小为止”。请注意,直到超过最大突发数才意味着完全不同于您所说的突发。您还将突发多余的请求混为一谈,我相信过多的请求意味着它在区域之上,而仍可能在最大突发以下
亨迪·爱侣湾

10

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;
  ...
}

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

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

如果添加nodelay:

location /login/ {
  limit_req zone=mylimit burst=20 nodelay;
  ...
}

使用nodelay参数,NGINX仍根据burst参数在队列中分配时隙,并强加配置的速率限制,但不通过间隔排队请求的转发来实现。相反,当请求“过早”到达时,只要队列中有可用的插槽,NGINX就会立即转发该请求。它将该插槽标记为“已占用”,直到经过适当的时间(在我们的示例中为100毫秒)后,该插槽才会释放给其他请求使用。


6

我看到的方式如下:

  1. 将尽可能快地处理请求,直到超过区域速率。区域速率是“平均”的,因此如果您的速率是1r/s且突发,则10您可以在10秒的窗口中有10个请求。

  2. 超过区域速率后:

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

    b。使用nodelay,最多可以burst尽快处理最多的请求。

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


3

该设置定义了是否将延迟请求以使其符合所需的速率,或者是否仅将其拒绝...速率限制是由服务器管理还是由责任传递给客户端。

nodelay 当下

请求将尽快处理;超过指定限制发送的任何请求都将被拒绝,并设置为limit_req_status

nodelay 缺席(又名延迟)

请求将以符合指定限制的速率进行处理。因此,例如,如果将速率设置为10 req / s,则将在> = .1(1 / rate)秒内处理每个请求,从而不允许超出速率,而允许备份请求。如果备份了足够多的请求以使存储桶溢出(也可以通过并发连接限制来阻止),则使用设置为的代码将其拒绝limit_req_status

详细信息在这里:https : //github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L263 在尚未通过限制,现在是延迟的情况下,该逻辑开始是可选地将应用于该请求。nodelay特别是来自指令的应用程序在这里起作用:https : //github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_limit_req_module.c#L495 导致上述值delay变为0触发处理程序立即返回NGX_DECLINED,从而将请求传递给下一个处理程序(而不是NGX_AGAIN将其有效地重新排队以再次处理)。


1

第一次阅读https://www.nginx.com/blog/rate-limiting-nginx/中的介绍时,我并不理解。

现在,我确信我能理解,并且我的答案是迄今为止最好的。:)

假设:10r/s已设置,则服务器的最大能力例如10000r/s为, 10r/ms并且目前只有1个客户端。

因此,这是10r/s per IP burst=40 nodelay和之间的主要区别10r/s per IP burst=40

在此处输入图片说明

正如https://www.nginx.com/blog/rate-limiting-nginx/所述我强烈建议您先阅读本文(“ 两阶段速率限制”部分除外),此行为解决了一个问题。哪一个?:

在我们的示例中,队列中的第20个数据包等待2秒被转发,这时对它的响应可能不再对客户端有用。

检查我所做的草稿,40th请求在处得到响应,1s而其他请求在处40th得到响应4s

这可以充分利用服务器的功能:在保持对x r/s给定客户端/ IP 的约束的同时,尽快发送回响应。

但是这里也有成本。费用为:

如果你有很多客户排队服务器比方说客户端ABC

如果没有nodelay,则请求的服务顺序与相似ABCABCABC
随着nodelay,顺序更有可能是AAABBBCCC


我想在这里总结一下文章https://www.nginx.com/blog/rate-limiting-nginx/

最重要的是,最重要的配置是x r/s

  1. x r/s 仅,多余的请求将立即被拒绝。

  2. x r/s+ burst,多余的请求排队。

1.与vs相比2.,代价是在客户端,排队的请求占据了后来的请求的机会,而后来的请求本来有机会得到服务。

例如,10r/s burst=20vs 10r/s11th应该在后一种情况下立即拒绝该请求,但是现在该请求已排队并且将得到处理。该11th请求占用了21th请求的机会。

  1. x r/s+ burst+ nodelay,已经说明。

PS:本文的“ 两阶段速率限制”部分非常令人困惑。我不明白,但这似乎无关紧要。

例如:

使用此配置后,以8 r / s连续发出请求流的客户端将遇到以下行为。

8转/秒?认真吗?如图所示,在3秒内有17个请求,17/3 = 8?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.