背景
我们线上有一个 dubbo 的服务,出现大量的 CLOSE_WAIT 状态的连接,这些 CLOSE_WAIT 的连接出现以后不会消失,这就有点意思了,于是做了一下分析记录如下。
首先从 TCP 的角度看一下 CLOSE_WAIT

CLOSE_WAIT 状态出现在被动关闭方,当收到对端 FIN 以后回复 ACK,但是自身没有发送 FIN 包之前。
所以这里的原因就很清楚了,出现永远存在的 CLOSE_WAIT 的连接是因为,收到了对端的 FIN 包,但是自己一直没有回复 FIN。通过抓包确实验证了这个的想法。

问题就落在了为什么没有回复 FIN,这是一个健康检查探测的请求,三次握手成功以后,探测服务会马上发送 FIN,理论上 dubbo 服务也会立刻回复 FIN,但是没有任何反应。
对于 dubbo 底层使用的 netty 来说,它就是一个普通的 tcp 服务端,无非就这几步:
- bind、listen
- 注册 accept 事件到 epoll
- epoll_wait 等待连接到来
- 连接到来时,调用 accept 接收连接
- 注册新连接的 EPOLLIN、EPOLLERR、EPOLLHUP 等事件到 epoll
- epoll_wait 等待事件发生
如果是没有发送 fin,有几个比较明显的可能原因。
- 第 2 步没有做,压根没有注

线上Dubbo服务出现大量CLOSE_WAIT状态连接,原因是Netty在处理TCP连接时,由于内存溢出(OOM)导致无法注册事件且未关闭连接。分析发现,Netty在accept连接并注册事件时,如果出现异常,连接保持打开状态,无法响应FIN包。通过模拟复现问题,提出在异常处理中关闭连接的解决方案。
最低0.47元/天 解锁文章
3019

被折叠的 条评论
为什么被折叠?



