Pio*_*źdź 2 nginx reverse-proxy 503-error high-load http-status-code-408
目前,我们的队列大小为 3000 个请求。
location /api/v2 {
limit_req zone=bursted burst=3000;
include /etc/nginx/proxy.conf;
}
Run Code Online (Sandbox Code Playgroud)
速率限制为每秒 10 个请求。
limit_req_zone $limit zone=api_slow:10m rate=1r/s;
limit_req_zone $server_name zone=bursted:10m rate=10r/s;
Run Code Online (Sandbox Code Playgroud)
保持活动超时为 30 秒。换句话说,当队列已满时,每 30 秒应拒绝 2700 个请求,并显示错误代码 408。
reset_timedout_connection on;
client_body_timeout 10;
send_timeout 2;
keepalive_timeout 30;
Run Code Online (Sandbox Code Playgroud)
在高峰时段,我在日志中找不到任何请求,由于超时,该请求被 NGINX 拒绝,错误代码为 408,而请求正在队列中等待转发到 servlet 容器。仅拒绝并返回 503 错误代码,这与请求速率开销相对应。
delaying request, excess: 2958.320, by zone "bursted"
limiting requests, excess: 3000.730 by zone "bursted"
Run Code Online (Sandbox Code Playgroud)
如果此类队列中的请求挂起时间过长,NGINX 是否会通过超时拒绝这些请求?这个超时是什么?它的配置在哪里?
nginx 速率限制和超时的工作原理似乎有点混乱。速率限制没有超时。您只需设置速率和队列大小。任何超出速率的请求都将添加到队列中以供稍后处理。一旦队列完全填满,任何其他请求都将被拒绝,并显示 503 状态代码。
在您的示例中,您设置的速率为每秒 10 个请求 (10r/s),突发大小为 3000,区域“突发”大小为 10 MB。此速率限制适用于每个定义的服务器的单独计数。
换句话说,您的服务器每 0.1 秒接受并处理一个请求,并且最多可以排队 3000 个超出的请求,然后以定义的速率处理这些请求:每 0.1 秒一个。您的突发区域可以存储大约 160.000 个 IP 地址。
这意味着如果 3011 个请求在一秒内到达,nginx 会立即处理前 10 个请求,并将另外 3000 个请求放入队列中,第 3011 个请求将被拒绝,并显示 503 状态代码。然后,队列将以每 0.1 秒一个请求的定义速率进行处理。只要没有新的请求到达,队列就会变短,新的请求可以再次添加到队列中。但是,虽然队列已容纳 3000 个请求,但每个额外的请求都将被拒绝,并显示 503 状态代码。
这种突发队列的线性处理行为可能会使您的网站显得缓慢。为了防止这种情况,您可以将nodelay
参数添加到limit_req zone=bursted burst=3000 nodelay;
. 这将使突发队列中的所有请求立即得到处理,同时将队列中的插槽标记为“已占用”,然后再次以定义的速率逐个插槽“释放”,以便随着时间的推移满足定义的速率限制。
limit_req_status 444;
顺便说一句:您可以通过添加到配置块来将拒绝请求的状态代码从 503 更改为 444 http
。
欲了解更多详情,请参阅:
您的配置中的两个超时:
这client_body_timeout 10;
将使您的服务器在请求后等待最多 10 秒才能发送客户端正文。如果在此时间内客户端没有发送正文,服务器将关闭连接并返回 408 状态码。
这keepalive_timeout 30;
将使您的服务器关闭 30 秒后仍然打开的与客户端的所有连接。但根据我的测试,请求在突发队列中等待的时间不计入keepalive_timeout。
归档时间: |
|
查看次数: |
5771 次 |
最近记录: |