我们使用HttpLimitReqModule nginx mondule 进行速率限制,发现它与我们的“维护模式”冲突,因为两个组件都使用http 状态码 503。
当限制被激活时(通过limit_req指令),nginx 通常会提供 503,但不幸的是使用了我们的维护模式位置,这导致我们的 Amazon S3 托管维护页面出现 302。限制请求的 302 不是一个好的结果。
我想知道其他人如何处理这个问题?例如,我是否应该为我们的维护页面使用不同的状态代码,但如果是这样,怎么办?
理想情况下,对于受限制的请求,我不希望提供任何页面,只需要 503 响应标头 - 它需要尽可能轻量级,因为关键是要阻止服务器不堪重负。
作为参考,这是我们用于“维护模式”的 nginx 配置:
server {
...
# Redirect processing of 503 error pages into a named location:
error_page 503 @maintenance;
# "Maintenance Mode" is off by default - Use a nginx variable to track state.
set $maintenance off;
# Switch on "Maintenance Mode" if a certain file exists.
if (-f /var/www/mysite/shared/maintenanceON) {
set $maintenance on;
}
if ($maintenance = on) {
return 503; # 503 - Service unavailable
}
location @maintenance {
# Redirect the request to our maintenance page in Amazon S3.
rewrite ^(.*)$ http://mysite.s3-website-us-east-1.amazonaws.com/ break;
}
...
# Process the php files - pass to php-fpm.
location ~ \.php {
# Limit aggressive bots and crawlers to 30 requests per minute.
limit_req zone=bots;
fastcgi_pass 127.0.0.1:$fastcgi_port;
}
...
使用 503 以外的状态代码作为“维护模式”。
正如我们可以清楚地看到的那样,无论如何,当您使用“维护模式”时,用户实际上并没有得到 503,因此在您的配置内部使用该状态代码没有任何好处。制作另一个代码(593?)并使用它。
或者更好的是,跳过额外的,当维护文件存在时直接
location
发送。rewrite
从 nginx 1.3.15 开始,有一个“ limit_req_status ”指令允许您指定限制器将返回的 http 响应代码。
http 状态 429 表示“
Too Many Requests
”——此代码已在RFC 6585 附加 HTTP 状态代码中被接受。例如,它用于Twitter REST API Rate Limiter。(迈克尔的回答也有效,因为在我的配置中 503 仅由 nginx 内部使用)。