一些運行在Nginx上的網站有時候會出現「502 Bad Gateway」錯誤,有些時候甚至頻繁的出現。如下是小編蒐集整理的一些Nginx 502錯誤的排查方法,供參考:php
Nginx 502錯誤的緣由比較多,是由於在代理模式下後端服務器出現問題引發的。這些錯誤通常都不是nginx自己的問題,必定要從後端找緣由!但nginx把這些出錯都攬在本身身上了,着實讓nginx的推廣者備受置疑,畢竟從字眼上理解,bad gateway?不就是bad nginx嗎?讓不瞭解的人看到,會直接把責任推在nginx身上,但願nginx下一個版本會把出錯提示寫稍微友好一些,至少不會是如今簡單的一句 502 Bad Gateway,另外還不忘附上本身的大名。mysql
Nginx 502的觸發條件nginx
502錯誤最一般的出現狀況就是後端主機當機。在upstream配置裏有這麼一項配置:proxy_next_upstream,這個配置指定了 nginx在從一個後端主機取數據遇到何種錯誤時會轉到下一個後端主機,裏頭寫上的就是會出現502的全部狀況拉,默認是error timeout。error就是當機、斷線之類的,timeout就是讀取堵塞超時,比較容易理解。我通常是全寫上的:程序員
proxy_next_upstream error timeout invalid_header http_500 http_503; 不過如今可能我要去掉http_500這一項了,http_500指定後端返回500錯誤時會轉一個主機,後端的jsp出錯的話,原本會打印一堆 stacktrace的錯誤信息,如今被502取代了。但公司的程序員可不這麼認爲,他們認定是nginx出現了錯誤,我實在沒空跟他們解釋502的原理 了……sql
503錯誤就能夠保留,由於後端一般是apache resin,若是apache死機就是error,但resin死機,僅僅是503,因此仍是有必要保留的。數據庫
解決辦法apache
遇到502問題,能夠優先考慮按照如下兩個步驟去解決。後端
一、查看當前的PHP FastCGI進程數是否夠用:服務器
複製代碼 代碼以下:socket
netstat -anpo | grep "php-cgi" | wc -l
若是實際使用的「FastCGI進程數」接近預設的「FastCGI進程數」,那麼,說明「FastCGI進程數」不夠用,須要增大。
二、部分PHP程序的執行時間超過了Nginx的等待時間,能夠適當增長nginx.conf配置文件中FastCGI的timeout時間,例如:
複製代碼 代碼以下:
http { fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; ...... } ......
php.ini中memory_limit設低了會出錯,修改了php.ini的memory_limit爲64M,重啓nginx,發現好了,原來是PHP的內存不足了。
若是這樣修改了還解決不了問題,能夠參考下面這些方案:
1、max-children和max-requests
一臺服務器上運行着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, 「127.0.0.1:9000″ 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 或者一個比較大的值:
打開 /usr/local/php/etc/php-fpm.conf調大如下兩個參數(根據服務器實際狀況,過大也不行)
複製代碼 代碼以下:
<value>5120</value><value>600</value>
而後重啓php-fpm。
2、增長緩衝區容量大小
將nginx的error log打開,發現「pstream sent too big header while reading response header from upstream」這樣的錯誤提示。查閱了一下資料,大意是nginx緩衝區有一個bug形成的,咱們網站的頁面消耗佔用緩衝區可能過大。參考老外寫的修 改辦法增長了緩衝區容量大小設置,502問題完全解決。後來系統管理員又對參數作了調整隻保留了2個設置參數:client head buffer,fastcgi buffer size。
3、request_terminate_timeout
若是主要是在一些post或者數據庫操做的時候出現502這種狀況,而不是在靜態頁面操做中常見,那麼能夠查看一下php-fpm.conf設置中的一項:
request_terminate_timeout
這個值是max_execution_time,就是fast-cgi的執行腳本時間。
0s
0s爲關閉,就是無限執行下去。(當時裝的時候沒仔細看就改了一個數字)問題解決了,執行很長時間也不會出錯了。優化fastcgi中,還能夠改改這個值5s 看看效果。
php-cgi進程數不夠用、php執行時間長、或者是php-cgi進程死掉,都會出現502錯誤。Nginx 502 Bad Gateway錯誤的解決辦法2
今天,個人VPS頻繁提示Nginx 502 Bad Gateway錯誤了,重啓了VPS解決以後又出現,很煩。有點想不通,前兩天網站達到了1290的訪問量都沒有出什麼問題,怎麼此次就出現了502 Bad Gateway?鬱悶啊!!!在搜索了好久,終於找到了很多相關的答案,但願修改以後不會再出現這個錯誤了。唉,既然在網上找了那麼久的答案,那固然得把有用的東西記錄下,省得我下次再去谷歌~
因爲我是採用了LNMP一鍵安裝包 ,出了問題確定要先到官方論壇去搜索下了,真好,官方有個這樣的置頂帖,你們先瞧瞧。
LNMP一鍵安裝包官方的:
第一種緣由:目前lnmp一鍵安裝包比較多的問題就是502 Bad Gateway,大部分狀況下緣由是在安裝php前,腳本中某些lib包可能沒有安裝上,形成php沒有編譯安裝成功。解決辦法:能夠嘗試根據lnmp一鍵安裝包中的腳本手動安裝一下,看看是什麼錯誤致使的。
第二種緣由:
在php.ini裏,eaccelerator配置項必定要放在Zend Optimizer配置以前,不然也可能引發502 Bad Gateway
第三種緣由:
在安裝好使用過程當中出現502問題,通常是由於默認php-cgi進程是5個,可能由於phpcgi進程不夠用而形成502,須要修改/usr/local/php/etc/php-fpm.conf 將其中的max_children值適當增長。
第四種緣由:
php執行超時,修改/usr/local/php/etc/php.ini 將max_execution_time 改成300
第五種緣由:
磁盤空間不足,如mysql日誌佔用大量空間
第六種緣由:
查看php-cgi進程是否在運行
也有網友給出了另外的解決辦法:
Nginx 502 Bad Gateway的含義是請求的PHP-CGI已經執行,可是因爲某種緣由(通常是讀取資源的問題)沒有執行完畢而致使PHP-CGI進程終止,通常來講Nginx 502 Bad Gateway和php-fpm.conf的設置有關。
php-fpm.conf有兩個相當重要的參數,一個是max_children,另外一個是request_terminate_timeout,可是這個值不是通用的,而是須要本身計算的。在安裝好使用過程當中出現502問題,通常是由於默認php-cgi進程是5個,可能由於phpcgi進程不夠用而形成502,須要修改/usr/local/php/etc/php-fpm.conf 將其中的max_children值適當增長。
計算的方式以下:
若是你的服務器性能足夠好,且寬帶資源足夠充足,PHP腳本沒有系循環或BUG的話你能夠直接將 request_terminate_timeout設置成0s。0s的含義是讓PHP-CGI一直執行下去而沒有時間限制。而若是你作不到這一點,也就 是說你的PHP-CGI可能出現某個BUG,或者你的寬帶不夠充足或者其餘的緣由致使你的PHP-CGI假死那麼就建議你給 request_terminate_timeout賦一個值,這個值能夠根據服務器的性能進行設定。通常來講性能越好你能夠設置越高,20分鐘-30分 鍾均可以。而max_children這個值又是怎麼計算出來的呢?這個值原則上是越大越好,php-cgi的進程多了就會處理的很快,排隊的請求就會不多。 設置max_children也須要根據服務器的性能進行設定,通常來講一臺服務器正常狀況下每個php-cgi所耗費的內存在20M左右。
按照官方的答案,排查了相關的可能,並結合了網友的答案,得出了下面的解決辦法。
一、查看php fastcgi的進程數(max_children值)
代碼:netstat -anpo | grep 「php-cgi」 | wc -l
5(假如顯示5)
二、查看當前進程
代碼:top觀察fastcgi進程數,假如使用的進程數等於或高於5個,說明須要增長(根據你機器實際情況而定)
三、調整/usr/local/php/etc/php-fpm.conf 的相關設置
<value name=」max_children」>10</value><value name=」request_terminate_timeout」>60s</value>max_children最多10個進程,按照每一個進程20MB內存,最多200MB。request_terminate_timeout執行的時間爲60秒,也就是1分鐘。