nginx 502 bad gateway


nginx 502 bad gateway

總結

一般是php問題居多,也需要調整相應的nginx參數,最后也可能是mysql假死

nginx問題

查看日志中的報錯error.log
一般設置路徑/usr/local/nginx/logs/nginx_error.log

nginx等待時間超時

Nginx代理過程,將業務服務器請求數據緩存到本地文件,再將文件數據轉發給請求客戶端。高並發的客戶端請求,必然要求服務器文件句柄的並發打開限制。

使用ulimit命令(ulimit -n),查看Linux系統文件句柄並發限制,默認是1024,我們可以改為65535(2 的 16 次方,這是系統端口的極限)。

修改的方法為:修改系統文件/etc/security/limits.conf,添加如下信息,並重新啟動系統生效。

修改nginx.conf配置參數

部分PHP程序的執行時間超過了Nginx的等待時間,可以適當增加nginx.conf配置文件中FastCGI的timeout時間,例如:

http { fastcgi_connect_timeout 300; # 鏈接 fastcgi_send_timeout 300; # 讀取 fastcgi_read_timeout 300; # 發請求 ...... }

fastcgi_read_timeout是指fastcgi進程向nginx進程發送response的整個過程的超時時間

fastcgi_send_timeout是指nginx進程向fastcgi進程發送request的整個過程的超時時間

這兩個選項默認都是秒(s),可以手動指定為分鍾(m),小時(h)等

php問題

一般是/usr/local/php/etc/php-fpm.conf三個參數(最主要的問題)

pm.max_children pm.max_requests request_terminate_timeout
php-cgi進程數不夠用、php執行時間長、或者是php-cgi進程死掉,都會出現502錯誤。

具體根據php-fpm.conf中error.log跟slow.log兩個日志來判斷

/usr/local/php/var/log/php-fpm.log /usr/local/php/var/log/php-fpm-slowlog.log

1.php進程池pm.max_children參數

netstat -anp | grep php | grep CONNECTED

ps aux | grep php-fpm 觀察fastcgi/php-fpm進程數,假如使用的進程數等於或高於5個,說明需要增加

vim /usr/local/php/etc/php-fpm.conf pm.max_children = 50

max_children是PHP-FPM Pool 最大的子進程數,他數值取決於你的服務器內存。
假設你打算給10G內存給當前配置的PHP-FPM Pool,一般一個PHP請求占用內存20M-30M,我們按站點每個PHP請求占用內存25M,這樣max_children = 10G/25M = 409。所以,這個值可以根據情況算出來

每個PHP請求占用內存可以在測試你的php程序時通過memory_get_peak_usage(true)這個函數獲得內存峰值,以此作為單個請求的程序內存消耗消耗量,並考慮進php-fpm本身的基礎內存消耗,可以得到一個近似的單進程內存消耗量。

  • 只要在峰值的時候所有PHP pool所耗內存低於我的有效內存80%算是合理的

pm.max_spare_servers這個參數值要小於pm.max_children的值,不然會啟動php-fpm失敗

2.pm.max_requests參數

我們知道這個參數的含義是php-fpm工作進程處理完多少請求后自動重啟,主要目的就是為了控制請求處理過程中的內存溢出,使得內存占用在一個可接受的范圍內。

max_requests = N 是指當每個children接受了N次請求以后,就會把自己殺死,然后重新建立一個children。

比如上面的值是1000,而你定義的是10240,那么fpm要超過10天才能殺死children並重建,這樣如果存在內存泄露的話,就會導致進程占用過多的內存而無法釋放,從而使fpm的處理能力降低,還會產生一些莫名其妙的錯誤。

但是如果你把這個值設置的過小,fpm頻繁的殺死children並重建,也會導致額外的開銷。

  • 這個參數依情況而定吧,具體沒有實驗測試過

3.request_terminate_timeout參數

max_requests是每個子進程重生之前處理的請求數, 默認值為unlimited(默認為1024),可以設置小一點(如500左右),這樣可以避免內存泄露帶來的問題

或者在/usr/local/php/etc/php.ini下的max_execution_time參數修改,百度這兩個值貌似沒有什么區別,最好的就是兩個都設置一下

request_terminate_timeout = 0s #表示關閉,即無限執行下去。

4.php權限問題

php-fpm.conf中定義屬主,屬組
listen.owner = nobody //定義屬主
listen.group = nobody //定義屬組
這里的nobody只的是nginx的用戶

5.php內存不足

php.ini中memory_limit設低了會出錯,修改了php.ini的memory_limit為64M,重啟nginx,發現好了,原來是PHP的內存不足了。

mysql假死

根據mysql日志排查,這種情況不多,但要注意,暫時沒有遇到過
一般引起mysql假死的原因有兩種:

  1. mysql假死了,你也請求不到后端的
  2. mysql慢查詢也會引起

mysql 的cpu占用率高,導致后台差不到數據也要注意

 

或者 

 

Nginx 502 Bad Gateway的含義是請求的PHP-CGI已經執行,但是由於某種原因(一般是讀取資源的問題)沒有執行完畢而導致PHP-CGI進程終止,一般來說Nginx 502 Bad Gateway和php-fpm.conf的設置有關。


常見的原因可能是php-cgi進程數不夠用、php執行時間長(mysql慢)、或者是php-cgi進程死掉,都會出現502錯誤。

1. 在安裝好的環境中,運行一段時間出現502問題,一般是因為默認php-cgi進程是5個,可能因為phpcgi進程不夠用而造成502,需要修改/usr/local/php/etc/php-fpm.conf 將其中的max_children值適當增加。

2. php執行超時,修改/usr/local/php/etc/php.ini 將max_execution_time 改為300

3. 磁盤空間不足,可以使用 # df -h命令查看磁盤使用量

4. php-cgi進程死掉了。


通常的排查方法如下:

1、查看php fastcgi的進程數(max_children值)

# netstat -anop | grep php-cgi | wc -l
# netstat -anpo | grep php-fpm | wc -l

1.JPG

假如顯示是5

2、查看當前進程
# ps aux | grep php-fpm 觀察fastcgi/php-fpm進程數,假如使用的進程數等於或高於5個,說明需要增加。

5.JPG

3、調整/usr/local/php/etc/php-fpm.conf 的相關設置

pm.max_children = 5
request_terminate_timeout = 60

3.JPG

4.JPG

max_children最多5個進程,按照每個進程20MB內存,最多100MB。也就是1分鍾。max_children增多,則php-cgi的進程多了就會處理的很快,排隊的請求就會很少。 但是設置max_children也需要根據服務器的性能進行設定,一般來說一台服務器正常情況下每一個php-cgi所耗費的內存在20M左右。根據自己服務器購買的內存來實際決定。
request_terminate_timeout執行的時間為60秒,request_terminate_timeout值可以根據服務器的性能進行設定。一般來說性能越好你可以設置越高,20分鍾-30分鍾都可以。

4. 部分PHP程序的執行時間超過了Nginx的等待時間,可以適當增加nginx.conf配置文件中FastCGI的timeout時間,例如:

http
{
......
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
......
}

 2.JPG

 

參考資料

https://www.cnblogs.com/irockcode/p/8336313.html

https://www.cnblogs.com/feng18/p/5148985.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM