php-fpm backlog參數優化

參考:http://phpmianshi.com/?id=92

 

一、問題分析

 

       1、分析php-fpm.slow.log發現沒有執行慢的地方,然後把目光放到了nginx 與php建立連接的階段上,使用tcpdump在服務器上抓包,

 

發現性能差的機器上存在大量的SYN3秒超時,並且會伴有請求頭的超時重傳。如下圖:

image.png

        看來兇手已經找到了:是SYN 超時。一般SYN 超時是由於服務端backlog引起的,在我們的應用中,nginx –> php-fpm,所以php-fpm相當於服務端,查看php-fpm配置發現 backlog值是 -1 

 

        抱着試試看的心態,改變了fpm配置backlog的值,測試發現把php-fpm的backlog值設爲:10 –262143 之間機器的性能恢復了(1-10因爲太小,所以性能不太理想),但是隻要大於262144,性能就又變差了。結合上面的問題,SYN超時一般是服務器端完成連接隊列滿導致的, 既然backlog值被設置成了somaxconn,那麼不應該出現內核中完成連接隊列滿的情況。

 

        從上面的測試我們可以認爲php-fpm是因爲沒有及時accept連接導致服務器不再接收TCP連接導致的,那麼fpm爲什麼會不及時accept呢? 

 

原來fpm 多個進程是監聽同一個套接字的,通過一個套接字鎖來保證同一時刻只有一個進程可以accept,多進程間搶鎖是需要消耗時間的,

 

在backlog被設置成-1的情況下,如果fpm沒有及時accept,那麼在併發量很大的情況下勢必會出現SYN 超時重連了。

 

 

二、結論

 

        綜上:性能差是由於php-fpm backlog參數設置爲-1,導致fpm沒能及時取出完成連接隊列的socket,出現SYN 超時,最終導致壓不上去,表現出性能差。

 

所以安裝php-fpm時backlog一定要重新設置,不能用fpm默認配置的-1 ,可以根據機器的併發量來設置,建議設置在1024以上,最好是2的冪值(因爲內核會調整成2的n次冪)。

 

如果您的業務機是2.6.18內核,同時發現php 機器性能特不合理,那麼就試試改一下fpm的backlog參數吧,您肯定會震驚的。。。。

 

 

三、備註

 

       在2.6.32內核上測試就不會出現這個問題,因爲2.6.32內核給listen socket分配空間時做了特殊的處理:

 

四、遺留問題

 

        雖然問題解決了,但是還存在兩個疑問。

 

        1、雖然通過測試可以確定backlog設置很大會出現SYN超時,但是還不能從原理上解釋?

 

         2、爲什麼同樣設置的-1,有的機器性能很好,有的卻很差呢?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章