我们使用HttpLimitReq模块nginx mondule 用于速率限制,并且发现它与我们的“维护模式“因为两个组件都使用http 状态代码 503。
当节流被激活时(通过限制请求数指令),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;
}
...
答案1
对于“维护模式”,请使用 503 以外的状态代码。
我们可以清楚地看到,当您使用“维护模式”时,用户实际上不会收到 503 状态代码,因此在配置中内部使用该状态代码没有任何好处。编写另一个代码(593?)并使用它。
或者更好的是,跳过额外的部分,当维护文件存在时直接location
发送。rewrite
if (-f /var/www/mysite/shared/maintenanceON) {
rewrite ^(.*)$ http://mysite.s3-website-us-east-1.amazonaws.com/ redirect;
}
答案2
从 nginx 1.3.15 开始,有一个“limit_req_status“指令允许您指定节流阀将返回的 http 响应代码。
# Define a limit request zone called "bots" that will track requests by IP.
limit_req_zone $binary_remote_addr zone=bots:20m rate=15r/s;
# 429 = Too Many Requests
limit_req_status 429;
http 状态 429 表示“ Too Many Requests
” - 此代码已被接受RFC 6585 其他 HTTP 状态代码. 例如,它用于Twitter REST API 速率限制器。
(迈克尔的回答也能工作,因为在我的配置中 503 仅由 nginx 内部使用)。