問題描述
最近有台服務器偶爾會報502錯誤,雖然量不多,每天就幾十個,但是也必須得找到原因,避免讓小問題變成大問題。
排查過程
502錯誤的原因,一般是對用戶訪問請求的響應超時造成的,一開始以為是請求量太大,超過了服務器目前的負載,但是查看了zabbix監控,發現問題時段的負載、內存、IO都沒有非常明顯的變化,服務器並沒有達到繁忙的狀態;查看這個時段請求的並發數,也不高。
然后查看nginx錯誤日志,發現該時段有如下報錯:
connect() to unix:/dev/shm/phpfpm.socket failed (11: Resource temporarily unavailable) while connecting to upstream
說明還是php-fpm進程不足導致的。
然后再觀察問題時段的php-fpm進程數變化情況:

發現問題時段php-fpm的進程數確實有比較明顯的變化,但是最高只到了75左右,並沒有達到我們設置的pm.max_children的數值。
綜上,結合502的特性,猜測:
是否是php-fpm子進程設置為dynamic模式,而我們的空閑進程數上限設置得比較低(目前設置的是35),然后當請求量增大時,創建子進程的速度跟不上請求增加的速度,進而導致部分請求無法得到響應,從而出現502?
驗證猜想
為了驗證上面的這個猜測,我在測試環境做了一些嘗試,即將php-fpm的pm.start_servers和pm.max_spare_servers都設置得比較小,然后進行ab測試,觀察php-fpm創建子進程的速度,發現果然和猜測的一樣,是非常慢的。當請求數比較多時,會因為創建php-fpm子進程的速度太慢,出現502的情況。
解決方案
增大php-fpm的pm.start_servers和pm.max_spare_servers的數值(最關鍵的是pm.max_spare_servers這個配置),保證請求量增加時,能夠有足夠的進程來處理請求,不需要在短時間內創建過多進程。
