502 bad gateway nginx 的錯誤的解決方案


 

總結

一般是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占用率高,導致后台差不到數據也要注意

 

 

個人公眾號謝謝各位老鐵支持


免責聲明!

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



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