分析:PHP長鏈接的硬傷

上篇博文《PHP的CURL報錯的排查記錄:短鏈接的成本真的很高啊》,我提到PHP長鏈接有個硬傷,那麼硬傷到底在哪裏呢?php

咱們寫一個簡易的memcache客戶端來分析下這個問題,數據庫等擴展的長鏈接同理,之因此要本身寫一個,是爲了更加清晰的看這個問題,不被擴展什麼的干擾。前端

$sock = pfsockopen("127.0.0.1",11211);
fwrite($sock,"set key 0 0 5\r\nvalue\r\n");
echo fread($sock,8);

而後將php-fpm的子進程數設置爲4個數據庫

pm.max_children = 4

而後咱們用Wireshark選擇Loopback抓包看一下,Wireshark過濾表達式服務器

tcp.dstport == 11211

結果以下架構

Wireshark抓包

從抓包結果的Info欄能夠看出,PHP在連續建立的4個鏈接後,後續的鏈接纔開始複用前面的鏈接(從發起請求的端口號能夠看出來)。併發

有沒有想到什麼?tcp

PHP的長鏈接是存在php-fpm子進程裏的,並非不少人想的那樣,一旦建立了一個長鏈接,後續就一直使用這一個長鏈接!而是每一個子進程使用一個長鏈接,子進程之間的長鏈接是不共享的。php-fpm

這樣有什麼很差嗎?oop

倘若咱們的PHP應用訪問量不高,併發量不大,咱們只須要開啓幾十個php-fpm子進程,每個子進程保持一個長鏈接這沒什麼問題。可是,若是訪問量很大,咱們必須開成百上千個php-fpm子進程的話,這麼多的長鏈接將會給應用服務器帶來很高的壓力,好比鏈接MySQL使用長鏈接,通常MySQL數據庫最大鏈接數也就幾千網站

SHOW VARIABLES like 'max_connections';//查看MySQL最大鏈接數

想象一下,假如你有幾十臺PHP服務器,每臺服務器都是成百上千的php-fpm子進程,一旦達到MySQL最大鏈接數,後續的鏈接就再也連不上數據庫了,並且這麼多的鏈接也會增長MySQL的壓力。

說到這裏,應該明白PHP長鏈接的硬傷了吧,也應該明白爲何一些網站作大後,要麼換掉PHP,要麼讓PHP僅僅作前端的緣由了吧。

更多架構、PHP、GO相關踩坑實踐技巧請關注個人公衆號:PHP架構師

相關文章
相關標籤/搜索