nginx 502 Bad Gateway 錯誤解決辦法

一些運行在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分鐘。

相關文章
相關標籤/搜索