如何防止nginx调节与维护模式冲突?

我们使用HttpLimitReqModule nginx mondule进行速率限制,并发现它与我们的“ 维护模式 ”冲突,因为这两个组件都使用http状态码503 。

当激活限制(通过limit_req指令)时,nginx通常会提供一个503,但不幸的是我们的维护模式位置被使用,导致我们的Amazon S3托pipe维护页面302。 一个302节制的请求不是一个好的结果

我想知道其他人如何处理这个问题? 例如,我应该为我们的维护页面使用不同的状态代码,但是如果是这样,是什么?

理想情况下,对于受限制的请求,我不希望提供任何页面,只有503响应头 – 它需要尽可能轻量级,因为整个问题是阻止服务器不堪重负。


作为参考,这是我们用于“维护模式”的nginxconfiguration:

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服务,因此在configuration中内部使用状态代码没有任何好处。 编写另一个代码(593?)并使用它。


或者更好的是,跳过额外的location ,直接在维护文件存在时直接发送rewrite

  if (-f /var/www/mysite/shared/maintenanceON) { rewrite ^(.*)$ http://mysite.s3-website-us-east-1.amazonaws.com/ redirect; } 

由于nginx 1.3.15有一个“ limit_req_status ”指令,允许你指定throttler将返回的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 Rate Limiter上 。

( 迈克尔的答案也适用,因为在我的configuration503只是由nginx内部使用)。