Nginx 502/504 Gateway time-out錯誤完美解決方案【轉發】

 

 

在安裝完Nginx+PHP-fpm+Mysql後,跑PHP的應用會常常出現504 Gateway Time-out 或者502 Bad Gateway的狀況。php

Nginx 504 Gateway Time-out 的含義是所請求的網關沒有請求到,簡單來講就是沒有請求到能夠執行的 PHP-CGI。這種狀況多是因爲 nginx 默認的 fastcgi 進程響應的緩衝區過小形成的, 這將致使 fastcgi 進程被掛起, 若是你的 fastcgi 服務對這個掛起處理的很差, 那麼最後就極有可能致使 504 Gateway Time-out。html

Nginx 504 Gateway time-out錯誤.jpg

通常看來, 這種狀況多是因爲nginx默認的fastcgi進程響應的緩衝區過小形成的, 這將致使fastcgi進程被掛起, 若是你的fastcgi服務對這個掛起處理的很差, 那麼最後就極有可能致使504 Gateway Time-out
如今的網站, 尤爲某些論壇有大量的回覆和不少內容的, 一個頁面甚至有幾百K
默認的fastcgi進程響應的緩衝區是8K, 咱們能夠設置大點nginx

在nginx.conf裏, 加入:sql

fastcgi_buffers 8 128k數據庫

這表示設置fastcgi緩衝區爲8×128k
固然若是您在進行某一項即時的操做, 可能須要nginx的超時參數調大點, 例如設置成60秒:apache

send_timeout 60;緩存

我只是調整了這兩個參數, 結果就是沒有再顯示那個超時, 能夠說效果不錯服務器

這個問題耽誤了我差很少4個小時的時間,網上有不少前輩們的解決方法,在這裏記錄下解決這個問題的思路。首先這個問題主要是由於PHP的Script執行時間太長了,已經超過nginx能接受的底線負載均衡

在nginx的日誌中會看到這樣的logdom

2012/08/11 13:39:45 [error] 30788#0: *1 upstream timed out (110: Connection timed out)

while reading response header from upstream, client: 127.0.0.1, server: www.cr173.com

request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "www.cr173.com

在php-fpm的日誌中會發現這樣的log

2012/08/11 13:39:45 [error] 30788#0: *1 upstream timed out (110: Connection timed out)

while reading response header from upstream, client: 127.0.0.1, server: www.cr173.com

request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "www.cr173.com"

通常來講,出現這樣的狀況是由於Nginx會從php-fpm的9000端口讀取fastcgi的執行結果,等來N久都不見回覆,因此就報504了。解決辦法很簡單,修改php的最長執行時間

; Maximum execution time of each script, in seconds; http://php.net/max-execution-time; 

Note: This directive is hardcoded to 0 for the CLI SAPI;

fix by Matt 2012.8.11

;max_execution_time = 3000

在這裏我註釋掉php.ini參數的時間限制。還有php-fpm裏的

;request_terminate_timeout = 0

這個參數會在php.ini中max_execution_time由於某些緣由不能正常工做纔會生效。

以前設置的是300s,安裝Magento的時候就一直就報504。後來索性修改到3000了。在Nginx的配置文件添加

#add by Matt 2012.8.11

fastcgi_read_timeout 3000;

fastcgi_connect_timeout 3000;

fastcgi_send_timeout 3000;

Magento你到底安裝多少sql文件啊?

PS:有時候緩存太小也會引發504,具體狀況還須要根據Nginx的日誌內容來分析。修改fastcgi的緩存大小:

fastcgi_buffers 2 256k;

fastcgi_buffer_size 128k;

fastcgi_busy_buffers_size 256k;

fastcgi_temp_file_write_size 256k;

VPS出現Nginx 504 Gateway time-out錯誤

西西 只對 Nginx.conf 和 php-fpm.conf 兩個配置文件作了一些修改,觀察一段時間,看看效果。

1.將 Nginx.conf 配置文件中相應參數設置爲以下:

命令:vi /usr/local/nginx/conf/nginx.conf (lnmp.org出品的lnmp一鍵安裝包路徑,其它請自行找目錄)

fastcgi_connect_timeout 300s; 

fastcgi_send_timeout 300s; 

fastcgi_read_timeout 300s; 

fastcgi_buffer_size 128k; 

fastcgi_buffers 8 128k;#8 128 

fastcgi_busy_buffers_size 256k; 

fastcgi_temp_file_write_size 256k; 

fastcgi_intercept_errors on;

2.將 php-fpm.conf 配置文件中相應參數設置爲以下值:

命令:vi /usr/local/php/etc/php-fpm.conf (lnmp.org出品的lnmp一鍵安裝包路徑,其它請自行找目錄)

<value name="max_children">9</value>(西西 購買的vps內存較小因此不能設置太大,應根據你的內存來設置) 

<value name="request_terminate_timeout">600s</value>(根據具體狀況設置,詳請查閱參考文章) 

<value name=」style」>apache-like </value>(php-fpm的默認靜態處理方式會使得php-cgi的進程長期佔用內存而沒法釋放,這也是致使nginx出錯的緣由之一,所以能夠將php-fpm的處理方式改爲apache模式。)

對 Linux  西西 也是菜鳥,只好照着別人的方法來設置了,等一段時間,沒什麼問題了,這個方法應該就是一個頗有效的方法了。

 

Nginx 502 Bad Gateway的含義是請求的PHP-CGI已經執行,可是因爲某種緣由(通常是讀取資源的問題)沒有執行完畢而致使PHP-CGI進程終止。

錯誤排查:

1 、查看fastcgi進程是否啓動

二、檢查系統中fastcgi進程的運行狀況

當系統中fastcGI進程數不夠用、php執行時間長、或者是php-cgi進程死掉也可能形成502錯誤

首先查看系統中開啓fastcGI的進程數

ps aux | grep "php-cgi" | wc -l 

查看有多少php-cgi來處理請求

netstat -anpo | grep "php-cgi" | grep -v "grep"  | wc -l 

若是處理請求的進程數接近開啓的進程數說明worker進程數配置太少,須要修改php-fpm.conf來增大php的進程數

三、fastcGI執行時間過長

能夠根據實際狀況調高nginx.conf中的如下參數:

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

增長了fastcgi的相應請求時間。可是我在實際中碰到了這個問題,設置到500,仍是會出現,只是比我設置120的時候要少一些。後來發現主要是在一些post或者數據庫操做的時候出現這種狀況,靜態頁面是不會出現的。
反覆的查問題,調試,也加大了CGI的進程數。
128 
256再加上去可能會變得很慢。佔用內存大了。
在php-fpm.conf設置中還有一項,可能當時沒注意到,無心中改了這個值。
request_terminate_timeout
這個值是max_execution_time,就是fast-cgi的執行腳本時間。
0s
0s爲關閉,就是無限執行下去。(當時裝的時候沒仔細看就改了一個數字)
發現,問題解決了,執行很長時間也不會出錯了
優化fastcgi中,還能夠改改這個值5s 。看看效果

四、頭部太大

nginx和apache同樣,有前段緩衝限制,能夠調整緩衝參數

fastcgi_buffer_size 32k;
fastcgi_buffers 8 32k;

若是你使用的是nginx的負載均衡Proxying,調整
proxy_buffer_size  16k;
proxy_buffers      4 16k;

五、https轉發配置錯誤

正確的配置方法
server_name www.mydomain.com;
location /myproj/repos {
set $fixed_destination $http_destination;
if ( $http_destination ~* ^https(.*)$ )
{
set $fixed_destination http$1;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Destination $fixed_destination;
proxy_pass http://subversion_hosts;
}

六、將nginx的error log打開,發現」pstream sent too big header while reading response header from upstream」這樣的錯誤提示,查閱了一下資料,大意是nginx緩衝區有一個bug形成的,咱們網站的頁面消耗佔用緩衝區可能過大。參考老外寫的修 改辦法增長了緩衝區容量大小設置,502問題完全解決,後來系統管理員又對參數作了調整隻保留了2個設置參數:client head buffer,fastcgi buffer size。

http://blog.rackcorp.com/?p=14

七、一臺服務器上運行着nginx php(fpm) xcache,訪問量日均 300W pv左右

最近常常會出現這樣的狀況: php頁面打開很慢,cpu使用率忽然降至很低,系統負載忽然升至很高,查看網卡的流量,也會發現忽然降到了很低。這種狀況只持續數秒鐘就恢復了
檢查php-fpm的日誌文件發現了一些線索
Sep 30 08:32:23.289973 [NOTICE] fpm_unix_init_main(), line 271: getrlimit(nofile): max:51200, cur:51200
Sep 30 08:32:23.290212 [NOTICE] fpm_sockets_init_main(), line 371: using inherited socket fd=10,
Sep 30 08:32:23.290342 [NOTICE] fpm_event_init_main(), line 109: libevent: using epoll
Sep 30 08:32:23.296426 [NOTICE] fpm_init(), line 47: fpm is running, pid 30587
在這幾句的前面,是1000多行的關閉children和開啓children的日誌 ?
原來,php-fpm有一個參數 max_requests ,該參數指明瞭,每一個children最多處理多少個請求後便會被關閉,默認的設置是500。由於php是把請求輪詢給每一個children,在大流量 下,每一個childre到達max_requests所用的時間都差很少,這樣就形成全部的children基本上在同一時間被關閉。
在這期間,nginx沒法將php文件轉交給php-fpm處理,因此cpu會降至很低(不用處理php,更不用執行sql),而負載會升至很高(關閉和開啓children、nginx等待php-fpm),網卡流量也降至很低(nginx沒法生成數據傳輸給客戶端)
解決問題很簡單,增長children的數量,而且將 max_requests 設置未 0 或者一個比較大的值,重啓php-fpm 

  Nginx 504 Gateway Time-out的含義是所請求的網關沒有請求到,簡單來講就是沒有請求到能夠執行的PHP-CGI。

  解決這兩個問題實際上是須要綜合思考的,通常來講Nginx 502 Bad Gateway和php-fpm.conf的設置有關,而Nginx 504 Gateway Time-out則是與nginx.conf的設置有關。

  而正確的設置須要考慮服務器自身的性能和訪客的數量等多重因素。

  fastcgi_connect_timeout 300s;

  fastcgi_send_timeout 300s;

  fastcgi_read_timeout 300s;

  fastcgi_buffer_size 128k;

  fastcgi_buffers 8 128k;#8 128

  fastcgi_busy_buffers_size 256k;

  fastcgi_temp_file_write_size 256k;

  fastcgi_intercept_errors on;

  這裏最主要的設置是前三條,即

  fastcgi_connect_timeout 300s;

  fastcgi_send_timeout 300s;

  fastcgi_read_timeout 300s;

  這裏規定了PHP-CGI的鏈接、發送和讀取的時間,300秒足夠用了,所以個人服務器不多出現504 Gateway Time-out這個錯誤。最關鍵的是php-fpm.conf的設置,這個會直接致使502 Bad Gateway和504 Gateway Time-out。

  下面咱們來仔細分析一下php-fpm.conf幾個重要的參數:

  php-fpm.conf有兩個相當重要的參數,一個是」max_children」,另外一個是」request_terminate_timeout」

  個人兩個設置的值一個是」40″,一個是」900″,可是這個值不是通用的,而是須要本身計算的。

  計算的方式以下:

  若是你的服務器性能足夠好,且寬帶資源足夠充足,PHP腳本沒有系循環或BUG的話你能夠直接將」request_terminate_timeout」設置成0s。0s的含義是讓PHP-CGI一直執行下去而沒有時間限制。而若是你作不到這一點,也就是說你的PHP-CGI可能出現某個BUG,或者你的寬帶不夠充足或者其餘的緣由致使你的PHP-CGI可以假死那麼就建議你給」request_terminate_timeout」賦一個值,這個值能夠根據你服務器的性能進行設定。通常來講性能越好你能夠設置越高,20分鐘-30分鐘均可以。因爲個人服務器PHP腳本須要長時間運行,有的可能會超過10分鐘所以我設置了900秒,這樣不會致使PHP-CGI死掉而出現502 Bad gateway這個錯誤。

  而」max_children」這個值又是怎麼計算出來的呢?這個值原則上是越大越好,php-cgi的進程多了就會處理的很快,排隊的請求就會不多。設置」max_children」也須要根據服務器的性能進行設定,通常來講一臺服務器正常狀況下每個php-cgi所耗費的內存在20M左右,所以個人」max_children」我設置成40個,20M*40=800M也就是說在峯值的時候全部PHP-CGI所耗內存在800M之內,低於個人有效內存1Gb。而若是個人」max_children」設置的較小,好比5-10個,那麼php-cgi就會「很累」,處理速度也很慢,等待的時間也較長。若是長時間沒有獲得處理的請求就會出現504 Gateway Time-out這個錯誤,而正在處理的很累的那幾個php-cgi若是遇到了問題就會出現502 Bad gateway這個錯誤。

 

轉載原文地址:

Nginx 504 Gateway time-out錯誤完美解決方案_西西軟件資訊
http://www.cr173.com/html/50534_1.html

http://www.server110.com/nginx/201401/5032.html

相關文章
相關標籤/搜索