在安裝完Nginx+PHP-fpm+Mysql后,跑PHP的應用會經常出現504 Gateway Time-out 或者502 Bad Gateway的情況。
Nginx 504 Gateway Time-out 的含義是所請求的網關沒有請求到,簡單來說就是沒有請求到可以執行的 PHP-CGI。這種情況可能是由於 nginx 默認的 fastcgi 進程響應的緩沖區太小造成的, 這將導致 fastcgi 進程被掛起, 如果你的 fastcgi 服務對這個掛起處理的不好, 那么最后就極有可能導致 504 Gateway Time-out。
一般看來, 這種情況可能是由於nginx默認的fastcgi進程響應的緩沖區太小造成的, 這將導致fastcgi進程被掛起, 如果你的fastcgi服務對這個掛起處理的不好, 那么最后就極有可能導致504 Gateway Time-out
現在的網站, 尤其某些論壇有大量的回復和很多內容的, 一個頁面甚至有幾百K
默認的fastcgi進程響應的緩沖區是8K, 我們可以設置大點
在nginx.conf里, 加入:
fastcgi_buffers 8 128k
這表示設置fastcgi緩沖區為8×128k
當然如果您在進行某一項即時的操作, 可能需要nginx的超時參數調大點, 例如設置成60秒:
send_timeout 60;
我只是調整了這兩個參數, 結果就是沒有再顯示那個超時, 可以說效果不錯
這個問題耽誤了我差不多4個小時的時間,網上有很多前輩們的解決方法,在這里記錄下解決這個問題的思路。首先這個問題主要是因為PHP的Script執行時間太長了,已經超過nginx能接受的底線。
在nginx的日志中會看到這樣的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
在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進程是否啟動
2、檢查系統中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的進程數
3、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 。看看效果
4、頭部太大
nginx和apache一樣,有前段緩沖限制,可以調整緩沖參數
fastcgi_buffer_size 32k;
fastcgi_buffers 8 32k;
如果你使用的是nginx的負載均衡Proxying,調整
proxy_buffer_size 16k;
proxy_buffers 4 16k;
5、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;
}
6、將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
7、一台服務器上運行着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
及