Nginx
如何防止 nginx 節流與維護模式衝突?
我們使用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; }