线上close wait问题分析
现象
线上falcon集群告警所有的告警信息都没有发送出来,但整个绘图组件正常,所有监控项可查
分析
链路分析
falcon架构如下
出现上述情况时,如果对整个链路熟悉,其实可以很快定位到jadge
, alarm
, redis
这三个组件的问题, 由于redis
集群中根本没有出现告警的数据,所以问题肯定是在jadge
上。
登录jadge的机器,执行ss | grep CLO | wc -l
,会发现大量的close wait
close wait分析
大量的close wait打满了机器的链接,导致jadge已经不能work;那么问题就变成了,为什么机器上会有大量的close wait? 祭出经典的tcp状态转换图
CLOSE_WAIT:接收到FIN 之后,被动关闭的一方进入此状态。具体动作是接收到 FIN,同时发送 ACK。之所以叫 CLOSE_WAIT 可以理解为被动关闭的一方此时正在等待上层应用程序发出关闭连接指令。前面已经说过,TCP关闭是全双工过程,这里客户端执行了主动关闭,被动方服务器端接收到FIN 后也需要调用 close 关闭,这个 CLOSE_WAIT 就是处于这个状态,等待发送 FIN,发送了FIN 则进入 LAST_ACK 状态
其实就是当对端主动关闭的时候,自己这端会进入CLOSE_WAIT
状态。
根据上面falcon的架构图,那jadge
的对端显然就是transfer
; 为什么transfer
会主动关闭? 看代码/open-falcon/falcon-plus/modules/transfer/sender/send_tasks.go
transfer
自己搞了一个conn pool来做rpc调用,只要当rpc call超时或者返回错误的时候,transfer
这端才会关闭链接。 所以看来还是到jadge
的rpc 请求超时了或者出错了,其实第一步的时候,我们看jadge的日志,也已经能看出蛛丝马迹了;这个rpc call 为什么超时或出错,就只能查看jadge
的代码了
jadge代码分析
/open-falcon/falcon-plus/modules/judge/rpc/rpc.go
这个rpc call的方法被修改过, 具体CheckNeedJudage
不太好展开了, 但归结的原因就是这个方法中由调用了rpc call,而且缓存失效,导致请求击穿,下游又被打爆,返回不回来
总结
线上问题分析
- 遇到问题不要慌,先拿出手机,发个朋友圈
- 看日志,各种日志, 从日志中找寻蛛丝马迹
- 看代码, 不要陷入细节, 看主要逻辑,链路
- 二分法调试,print大法