返回顶部
  • 发帖数42
  • 粉丝1

现就职于某世界500强区块链团队,从事区块链底层研究以及BAAS平台搭建。精通区块链底层存储、共识等技术,职业方向偏重联盟链体系

[开发语言] PHP进程卡死和MySQL超时时间的设置方法

[复制链接]
超级玛丽 显示全部楼层 发表于 2020-12-1 09:15:25 |阅读模式 打印 上一主题 下一主题
最近线上一台服务器的nginx总是会有一部分请求(不是所有请求)报upstream timed out (110: Connection timed out) while connecting to upstream的错误,看起来像是后端的phpcgi进程出问题了,但如果phpcgi进程有问题,不是应该所有请求都会报错才对么,于是展开排查。
排查原因
在我们服务器上,PHP是使用9006端口进行监听的,执行netstat -an | grep 9006命令查看相关连接的网络状态,看到有一部分连接处于CLOSE_WAIT状态:

  1. tcp        0      0 10.0.0.188:9006          10.0.0.52:37316         CLOSE_WAIT  
  2. tcp        0      0 10.0.0.188:9006          10.0.0.52:37292         CLOSE_WAIT  
  3. tcp        0      0 10.0.0.188:9006          10.0.0.52:37300         CLOSE_WAIT  
  4. tcp        0      0 10.0.0.188:9006          10.0.0.52:37302         CLOSE_WAIT  
  5. tcp        0      0 10.0.0.188:9006          10.0.0.52:37234         CLOSE_WAIT
复制代码

奇怪的是,这些连接一直停留在CLOSE_WAIT的状态,不会变化,所以应该就是这些连接导致PHP进程被卡死,无法处理新的请求,从而导致部分请求报Connection timed out错误的。
根据TCP连接的四次挥手过程,CLOSE_WAIT状态是连接被关闭方才会出现的。nginx调用PHP,PHP响应太慢导致nginx超时,继而nginx主动关闭跟PHP的TCP连接,因此PHP进程是被关闭方,这个没啥问题。但PHP进程在收到nginx的关闭请求后,应该也跟着关闭才对,但实际没有,而是停留在了CLOSE_WAIT状态,说明PHP被某些东西卡住了,没办法关闭连接。
于是使用strace -p PHP进程ID查看PHP卡在了什么地方,等了一两分钟,strace命令什么东西都没输出,说明PHP进程是卡在了某个系统调用:
猜想会不会是mysql导致PHP卡死呢,于是根据显示的连接端口号10465,到mysql服务器上查看这个端口的连接情况,发现居然没有这个端口的TCP连接。这就神奇了,这里我只能猜测是:PHP成功跟mysql服务器建立TCP连接,但由于丢包或者防火墙拦截等奇怪的原因,PHP没有收到mysql的greeting packet,于是导致PHP一直在这里空等。后面mysql服务器主动断开TCP连接,但发送的FIN包也被拦截了,导致收不到PHP的ACK回应,于是mysql继续释放了这个连接。于是就出现了这个连接在PHP端是ESTABLISHED状态,但在mysql端却不存在这个连接的情况。
确认和模拟测试
为了确认到底是不是mysql连接卡死了PHP,使用gdb -p PHP进程ID进行调试,上面lsof命令显示mysql的连接对应的文件描述符是5u,gdb里输入命令call close(5)强制把这个连接关闭,关闭后PHP进程的CLOSE_WAIT状态马上消失了,证明确实是这个连接卡住了PHP。
接着我尝试模拟“成功建立TCP连接,但收不到mysql greeting packet”的这种情景,看PHP会不会卡死,测试代码如下:

  1. $mysql = new mysqli();
  2. $mysql->real_connect('45.113.192.102', 'root', 'xxx', 'xxx', 80);
复制代码






回复

使用道具 举报

精彩评论3

天才儿童Caya 显示全部楼层 发表于 2020-12-1 09:38:53
学习了
回复

使用道具 举报

admin 显示全部楼层 发表于 2020-12-1 09:39:17
方法不错啊
回复

使用道具 举报

超级玛丽 显示全部楼层 发表于 2020-12-1 10:36:11
谢谢捧场啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

星点互联 成立于2014年8月,是目前国内优秀的开源技术社区,拥有超过300万会员,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作