上篇博文《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
结果以下架构
从抓包结果的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架构师