close wait 过多原因_从CLOSE_WAIT状态说TCP协议之4次挥手

最近机房变迁,运维部署新的生产环境发现了老项目的一个bug:该项目所在服务器的tcp连接中为CLOSE_WAIT状态的连接数量很多(会占用大量资源)。提醒开发需要注意是否是代码的问题,检查代码发现确实在某些地方发起http请求之后连接未关闭,处理之后恢复了正常。

那么什么是CLOSE_WAIT状态的连接呢?

首先说一说TCP协议中,断开连接的流程,引用《网络是怎样连接的》这本书中的描述:

和服务器的通信结束之后,用来通信的套接字也就不会再使用了,这 时我们就可以删除这个套接字了。不过,套接字并不会立即被删除,而是 会等待一段时间之后再被删除。 等待这段时间是为了防止误操作,引发误操作的原因有很多,这里无 法全部列举,下面来举一个最容易理解的例子。假设和图 2.12 的过程相 反,客户端先发起断开,则断开的操作顺序如下。
  1. 客户端发送 FIN
  2. 服务器返回 ACK 号
  3. 服务器发送 FIN
  4. 客户端返回 ACK 号
如果最后客户端返回的 ACK 号丢失了,结果会如何呢?这时,服务 器没有接收到 ACK 号,可能会重发一次 FIN。如果这时客户端的套接字已 经删除了,会发生什么事呢?套接字被删除,那么套接字中保存的控制信 息也就跟着消失了,套接字对应的端口号就会被释放出来。这时,如果别 的应用程序要创建套接字,新套接字碰巧又被分配了同一个端口号 B,而服 务器重发的 FIN 正好到达,会怎么样呢?本来这个 FIN 是要发给刚刚删除 A 如果接收缓冲区中还有剩余的已接收数据,则这些数据会被传递给应用程序。 B 客户端的端口号是从空闲的端口号中随意选择的。 2.4.2 删除套接字 2.4 从服务器断开并删除套接字 的那个套接字的,但新套接字具有相同的端口号,于是这个 FIN 就会错误 地跑到新套接字里面,新套接字就开始执行断开操作了。之所以不马上删 除套接字,就是为了防止这样的误操作。 至于具体等待多长时间,这和包重传的操作方式有关。网络包丢失之后 会进行重传,这个操作通常要持续几分钟。如果重传了几分钟之后依然无 效,则停止重传。在这段时间内,网络中可能存在重传的包,也就有可能发 生前面讲到的这种误操作,因此需要等待到重传完全结束。协议中对于这 个等待时间没有明确的规定,一般来说会等待几分钟之后再删除套接字。

具体我们关注的是这4步断开操作,也就是常说的4次挥手。

  1. 客户端发送 FIN
  2. 服务器返回 ACK 号
  3. 服务器发送 FIN
  4. 客户端返回 ACK 号

这4步详细的来说,应该是如下:

  1. 客户端发送一个FIN,用来关闭客户端到服务器的数据传送,此后客户端进入FIN_WAIT_1状态。
  2. 服务器收到FIN后,进入CLOSE_WAIT状态。正常情况下会发送一个ACK给客户端,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),
  3. 服务器发送一个FIN,用来关闭服务器到客户端的数据传送,服务器进入LAST_ACK状态。
  4. 客户端收到FIN后,客户端进入TIME_WAIT状态,接着发送一个ACK给服务器,确认序号为收到序号+1,服务器进入CLOSED状态,完成四次挥手。

也就是说,第二步进入了CLOSE_WAIT状态,而服务器中CLOSE_WAIT状态过多说明服务器没有返回ack给客户端。检查代码发现某些地方使用完连接之后没有释放连接,修改代码之后,恢复了正常,连接进入TIME_WAIT状态,随后被系统释放。

更多的关于TCP相关介绍可以参考下面的博文:

理解TCP/IP三次握手与四次挥手的正确姿势 - 吉米乐享驿站 - 博客园​www.cnblogs.com
8209b88c16331d7cccddfe58ec2fcc4b.png
TCP协议端口状态说明:CLOSE-WAIT、TIME-WAIT 、LISTENING、SYN_SENT、ESTABLISHED、LAST-ACK ...​www.cnblogs.com
3d71873981bcbef1f7206ea86f4d5d11.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值