總結
一般是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假死的原因有兩種:
- mysql假死了,你也請求不到后端的
- mysql慢查詢也會引起
mysql 的cpu占用率高,導致后台差不到數據也要注意