1. 程式人生 > >Nginx中502和504錯誤詳解

Nginx中502和504錯誤詳解

在使用Nginx時,經常會碰到502 Bad Gateway和504 Gateway Time-out錯誤,下面以Nginx+PHP-FPM來分析下這兩種常見錯誤的原因和解決方案。 1.502 Bad Gateway錯誤  在php.ini和php-fpm.conf中分別有這樣兩個配置項:max_execution_time和request_terminate_timeout。 這兩項都是用來配置一個PHP指令碼的最大執行時間的。當超過這個時間時,PHP-FPM不只會終止指令碼的執行, 還會終止執行指令碼的Worker程序。所以Nginx會發現與自己通訊的連線斷掉了,就會返回給客戶端502錯誤。 以PHP-FPM的request_terminate_timeout=30秒時為例,報502 Bad Gateway錯誤的具體資訊如下:
1)Nginx錯誤訪問日誌:      2013/09/19 01:09:00 [error] 27600#0: *78887 recv() failed (104: Connection reset by peer) while reading response header from upstream,       client: 192.168.1.101, server: test.com, request: "POST /index.php HTTP/1.1", upstream: "fastcgi://unix:/dev/shm/php-fcgi.sock:",       host: "test.com", referrer: "http://test.com/index.php"

2)PHP-FPM報錯日誌:
     WARNING:  child 25708 exited on signal 15 (SIGTERM) after 21008.883410 seconds from start
所以只需將這兩項的值調大一些就可以讓PHP指令碼不會因為執行時間長而被終止了。request_terminate_timeout可以覆蓋max_execution_time, 所以如果不想改全域性的php.ini,那隻改PHP-FPM的配置就可以了。 此外要注意的是Nginx的upstream模組中的max_fail和fail_timeout兩項。有時Nginx與上游伺服器(如Tomcat、FastCGI)的通訊只是偶然斷掉了,
但max_fail如果設定的比較小的話,那麼在接下來的fail_timeout時間內,Nginx都會認為上游伺服器掛掉了,都會返回502錯誤。 所以可以將max_fail調大一些,將fail_timeout調小一些。 2.504 Gateway Time-out錯誤 PHP-FPM設定的指令碼最大執行時間已經夠長了,但執行耗時PHP指令碼時,發現Nginx報錯從502變為504了。這是為什麼呢? 因為我們修改的只是PHP的配置,Nginx中也有關於與上游伺服器通訊超時時間的配置factcgi_connect/read/send_timeout。 以Nginx超時時間為90秒,PHP-FPM超時時間為300秒為例,報504 Gateway Timeout錯誤時的Nginx錯誤訪問日誌如下:      2013/09/19 00:55:51 [error] 27600#0: *78877 upstream timed out (110: Connection timed out) while reading response header from upstream,       client: 192.168.1.101, server: test.com, request: "POST /index.php HTTP/1.1", upstream: "fastcgi://unix:/dev/shm/php-fcgi.sock:",       host: "test.com", referrer: "http://test.com/index.php" 調高這三項的值(主要是read和send兩項,預設不配置的話Nginx會將超時時間設為60秒)之後,504錯誤也解決了。 而且這三項配置可以配置在http、server級別,也可以配置在location級別。擔心影響其他應用的話,就配置在自己應用的location中吧。 要注意的是factcgi_connect/read/send_timeout是對FastCGI生效的,而proxy_connect/read/send_timeout是對proxy_pass生效的。 配置舉例:
location ~ \.php$ {
                root                    /home/cdai/test.com;
                include                 fastcgi_params;
                fastcgi_connect_timeout      180;
                fastcgi_read_timeout            600;
                fastcgi_send_timeout            600;
                fastcgi_pass            unix:/dev/shm/php-fcgi.sock;
                fastcgi_index           index.php;
                fastcgi_param          SCRIPT_FILENAME /home/cdai/test.com$fastcgi_script_name;
     }
參考資料 1.大戰suhosin