好久沒寫部落格了,因為沒有啥可寫。
之所以有此疑問,是因為看了一篇大牛的文章:PHP升級導致系統負載過高問題分析。看完後,其中有些文字觸發了我這個想法,也想驗證一下。
方案,用tcpdump抓包,用strace擷取系統調用
tcpdump port 8080 and port 9000 -s 0 -w temp
8080是nginx的服務連接埠,9000是php-fpm服務的連接埠,抓這兩個連接埠是想看到瀏覽器、nginx、php-fpm三者之間的互動。抓完包後,用wireshark分析,如下:
tcp.port==46540 or tcp.port == 54352 //上面語句為wireshark的過濾文法,用於篩選我們感興趣的包
解釋如下:
1,46540是瀏覽器的連接埠,http-alt是nginx,54352是nginx請求php-fpm的連接埠,cslistener是php-fpm
2,因為我所有的操作都是在一台機器上,包括瀏覽器訪問,所以所有的IP都是127.0.0.1
3,
A:圖中第一部分,代表瀏覽器和nginx的三向交握的過程。
B:圖中第二部分,代表瀏覽器向nginx請求一個URL。
C:圖中第三部分,代表nginx與php-fpm三向交握的過程。
D:圖中第四部分,代表nginx將瀏覽器的請求轉寄給php-fpm。
E:圖中第五部分的11,13,14行,代表瀏覽器主動關閉了與nginx之間的串連。為什麼關閉呢,因為我不斷的重新整理頁面,在第二次重新整理的時候,瀏覽器會關閉上一次的請求。
為什麼是三次關閉,而不是四次握手關閉呢?因為第13行其實是兩個包合成一個包發送了,這應該算tcp的最佳化吧。
F:圖中第五部分的12,25行,代表nginx將瀏覽器關閉串連的訊息,告訴了php-fpm。
G:圖中第六部分,通過左邊的時間可以發現,是5秒種之後,php-fpm試圖向nginx返回它?染後的頁面,但nginx直接reset掉了這個串連。
為什麼是5秒種之後返回呢,因為我在php程式的第一行sleep(5),用於類比時間較長的商務邏輯處理。
分析到這裡,結論已經很明顯了,就是:
瀏覽器關閉請求後,nginx會通知到php-fpm,但php-fpm忽略了這個通知,繼續處理,直到發送處理結果時,才知道了串連已經被關閉。
我想在這裡,php-fpm還是有可以最佳化的空間的。
大家可以看下strace的結果,也可以驗證上面的結論。