Nginx

如何防止 nginx 節流與維護模式衝突?

  • June 12, 2014

我們使用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;
   }
   ...

從 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 Rate Limiter

邁克爾的回答也有效,因為在我的配置中 503 僅由 nginx 內部使用)。

使用 503 以外的狀態程式碼作為“維護模式”。

正如我們可以清楚地看到的那樣,無論如何,當您使用“維護模式”時,使用者實際上並沒有得到 503,因此在您的配置內部使用該狀態程式碼沒有任何好處。製作另一個程式碼(593?)並使用它。


或者更好的是,跳過額外的,當維護文件存在時直接location發送。rewrite

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

引用自:https://serverfault.com/questions/554682