要说清楚事情,不介绍下背景和环境好像不行啊
公司内部有一套RPC服务框架,java开发的,rpc协议用的redis
我所在的部门没java人手,但夸部门的数据交互又越来越多,一开始用http 接口性能不好,qps到2-3千的时候调用方经常发生各种curl 网络错误,导致拿不到数据,影响很不好
所以后来自己拿 php+swoole 实现RPC服务,延用公司的框架,协议和服务注册啥的都保持一致,就是具体业务用php来实现

绿色那块-中间椭圆的就是这次出问题的服务
我们可能会被PHP-FPM和其他RPC服务请求,也可能请求其他RPC服务和DB, 这样说应该清楚了吧
发现:收到zabbix发的报警 <code>PROBLEM: system close_wait [9522>5300], 首次报警</code>
脑子想了下,通常如果出问题都是调用方反馈,这次调用方没反馈应该没影响到具体业务,也没啥其它好确认的,直接上服务器看吧
<code>ss -ant | grep CLOSE-WAIT</code> 确认下果然是这样
close-wait 具体含义简单说下,看图
这是tcp的挥手图,<code>当主动关闭的一方发出FIN包,被动方回复ACK后自己就进入CLOSE_WAIT状态,正常情况下,被动方稍后就应该发出FIN包,并确认收到ACK回复,然后连接就可以正常关闭了</code>
很显然由于某些原因,我们的swoole程序(被动方)没能发出FIN包,这个为什么回头再分析,先把报警解决了
close_wait 是不会自动消失的,根据上面<code>ss -ant</code> 结果配合 <code>lsof -i :{$port}</code> 查到具体的服务,<code>隔离-重启-恢复</code>这个服务, 当然了<code>ss -ant</code> 的结果要保存下来,等下要分析具体谁跟我断了。。。
<code>ss -ant</code> 的结果看了下,close_wait 的 <code>Foreign Address</code> 基本都是RPC(java), 很多都是常用服务,整个公司都在用,基本排除是对方的原因
这次有2台机器都出现了问题,但2台机器上引起close_wait的service进程是不一样的,但有个特征就是<code>请求量很少</code>
因为 swoole 不忙,导致建立的socket连接超过了<code>闲置时间</code>,然后对方就觉得timeout了,然后主动断开了
还注意到close_wait 对方很多是按理不应该用到的rpc服务,我猜这个应该是php代码没写好有关系。 看开头的背景也知道,用swoole搭服务时间还是很紧张的,业务逻辑基本都是直接用的http api那套代码,而swoole是常驻内存的,本来某些变量/连接在api那套里面随着请求结束就回收了,但是在swoole里不会
我觉得基本就是onClose这里出了问题;我看了下php的error log, 没发现fatal error;
我们4台机器,其中2台发生问题,而且是不同的服务。加上用关键字<code>swoole close wait</code> google 没有发现案例。基本排除是swoole的问题,还是我使用的姿势不对然后有几率导致发生这个问题
然后就没有然后了,这4个机器的服务也跑了一年多了,第一次发生这个情况,我又不懂系统原理和c,加上案发现场现在也关闭了
这2个不活跃的服务配置的worker num 都是96个, 其中一个是同事开发的,使用的默认配置(默认配置是有个配置文件,我弄的,我好像没讲过要调低),另一个一开始请求量多,后来业务下了,也忘了调低
整理了下,请求量低的服务 worker number 都调低
<code>系统原理</code> 、 <code>网络</code>、 <code>c语言</code> 要尽量多学习, 不然承担这种<code>基础架构</code>服务,万一出了底层问题,你就不太能搞的定了,都是只能治标,不能治本