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的配置就可以了。
解決辦法是request_terminate_timeout設定為10s或者一個合理的值,或者給file_get_contents加一個超時引數。
$ctx
= stream_context_create(
array
(
`http`
=>
array
(
`timeout`
=> 10
//設定一個超時時間,單位為秒
)
)
);
file_get_contents
(
$str
, 0,
$ctx
);
此外要注意的是Nginx的upstream模組中的max_fail和fail_timeout兩項。有時Nginx與上游伺服器(如Tomcat、FastCGI)的通訊只是偶然斷掉了,但max_fail如果設定的比較小的話,那麼在接下來的fail_timeout時間內,Nginx都會認為上游伺服器掛掉了,都會返回502錯誤。所以可以將max_fail調大一些,將fail_timeout調小一些。
2、max_requests引數配置不當,可能會引起間歇性502錯誤:
pm.max_requests = 1000
#設定每個子程式重生之前服務的請求數. 對於可能存在記憶體洩漏的第三方模組來說是非常有用的. 如果設定為 `0` 則一直接受請求. 等同於 PHP_FCGI_MAX_REQUESTS 環境變數. 預設值: 0.
這段配置的意思是,當一個 PHP-CGI 程式處理的請求數累積到 500 個後,自動重啟該程式。
但是為什麼要重啟程式呢?
一般在專案中,我們多多少少都會用到一些 PHP 的第三方庫,這些第三方庫經常存在記憶體洩漏問題,如果不定期重啟 PHP-CGI 程式,勢必造成記憶體使用量不斷增長。因此 PHP-FPM 作為 PHP-CGI 的管理器,提供了這麼一項監控功能,對請求達到指定次數的 PHP-CGI 程式進行重啟,保證記憶體使用量不增長。
正是因為這個機制,在高併發的站點中,經常導致 502 錯誤,我猜測原因是 PHP-FPM 對從 NGINX 過來的請求佇列沒處理好。不過我目前用的還是 PHP 5.3.2,不知道在 PHP 5.3.3 中是否還存在這個問題。
目前我們的解決方法是,把這個值儘量設定大些,儘可能減少 PHP-CGI 重新 SPAWN 的次數,同時也能提高總體效能。在我們自己實際的生產環境中發現,記憶體洩漏並不明顯,因此我們將這個值設定得非常大(204800)。大家要根據自己的實際情況設定這個值,不能盲目地加大。
話說回來,這套機制目的只為保證 PHP-CGI 不過分地佔用記憶體,為何不通過檢測記憶體的方式來處理呢?我非常認同高春輝所說的,通過設定程式的峰值內在佔用量來重啟 PHP-CGI 程式,會是更好的一個解決方案。
3.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;
}
相關文章
- nginx 502 和 504 超時演示Nginx
- nginx “504 Gateway Time-out”錯誤NginxGateway
- 500 501 502 503 504 505 伺服器錯誤伺服器
- Nginx報504 gateway timeout錯誤的解決方法NginxGateway
- Nginx502錯誤原因和解決方法總結Nginx
- Nginx 報錯 504 Gateway Time-out 的解決方法NginxGateway
- Nginx+PHP(php-fpm)遇到的502BadGateway錯誤NginxPHPGateway
- ORA-600(504)(row cache objects)錯誤Object
- 解Bug之路-Nginx 502 Bad GatewayNginxGateway
- HTTP 499狀態碼 nginx下499錯誤詳解HTTPNginx
- nginx 錯誤除錯Nginx除錯
- Nginx 中 nginx.conf 詳解Nginx
- docker中建立Nginx和php-pfm 報file not find .錯誤。DockerNginxPHP
- 公司網站報502錯誤怎麼辦網站
- nginx的502問題Nginx
- Win10系統愛奇藝出現504錯誤程式碼的解決方法Win10
- Js錯誤Error物件詳解JSError物件
- pb錯誤程式碼詳解
- nginx 配置 proxy_next_upstream 會出現未預期 502 錯誤問題排查Nginx
- nginx出現403錯誤的解決方法Nginx
- HTTP代理504閘道器超時錯誤如何修復?HTTP
- http代理504閘道器超時錯誤原因介紹HTTP
- 如何修復http代理504閘道器超時錯誤HTTP
- ADFS4.0 使用nginx做反向代理訪問報502錯的解決方法Nginx
- Docker Nginx 502 Bad getwayDockerNginx
- ORA-04031錯誤詳解
- 雲伺服器出現502錯誤怎麼辦伺服器
- 網站提示502 錯誤閘道器怎麼辦網站
- Nginx的工作原理和配置詳解Nginx
- nginx 詳解Nginx
- Nginx詳解Nginx
- Linux下安裝oracle11g和錯誤詳解LinuxOracle
- RxJava2 錯誤處理詳解RxJava
- C/C++常見錯誤詳解C++
- ORA-01555錯誤詳解
- nginx FastCGI錯誤Primary script unknown解決辦法NginxAST
- Nginx常見錯誤程式碼總結和分析方法Nginx
- 402、403、404、502等閘道器錯誤的解決辦法都在這了!