记录一次 “服务器 CLOSE_WAIT”堆积的解决过程

一 前提与背景

1 前提

只要出现CLOSE_WAIT累积一定是自己服务写的有问题

2 背景

给自己服务访问第三方服务加了连接池后,压测时候发现请求结束后有很多连接处于close_wait状态,且一直不结束

用连接池的原因是为了连接复用与连接控制
在这里插入图片描述

二 解决过程

1 知识点回顾

在正式解决该问题前,先回顾下“TCP四次挥手”过程

在这里插入图片描述
理解四次挥手时候不要用 服务端-客户端这样去理解每次挥手过程, 而是要以谁是主动断开连接的(即主动发送 FIN)为标准

2 服务是如何解决

如【背景】图所示,处于 CLOSE_WAIT的是【访问 8501接口】 和 【访问 80端口】的第三方服务连接。

  • 问题1: 所以这里疑问来了,是我的服务主动访问第三方服务的,为什么会出现CLOSE_WAIT?

  • 答案1: 如【知识点回顾】所说, 要以谁是主动断开连接的来判断; 这里我的服务连接状态是CLOSE_WAIT,那么一定是我访问的第三方服务发送的FIN断开请求, 我是被动关闭了连接请求

  • 问题2: 为啥CLOSE_WAIT 不释放 ?

  • 答案2: 一直处于CLOSE_WAIT 意味着 四次挥手过程中 第三次挥手一直没有挥手,也就是说我的服务一直没有给第三方服务发送FIN包

基于这个思路,那么第三方服务主动发送断开连接的情况可能是:第三方服务报错了(可能是超时,服务错误,连接问题等)。

看了下log 确实存在第三方服务报错。

在这里插入图片描述
证明了第一个问题后,第二问题“为什么我的服务不给第三方服务发送FIN包?”, 首先看下我的服务是如何写的

在这里插入图片描述
很简单的代码, POST访问第三方服务 + 异常判断与获取

可以理解是访问了第三方服务出错了,但是处于CLOSE_WAIT状态不变了, 也就是说一定需要我的服务主动给第三方服务发送FIN

了解到我的连接池中的连接,在访问第三方服务报错后,并不会主动断开连接,需要自己处理: 主动关闭出错的访问连接 。 简单的方案在执行完全部并发线程后关闭整个session

在这里插入图片描述
重启服务后测试发现服务CLOSE_WAIT状态的连接已经全部不在,当然不用担心新的连接问题,因为这次请求已经结束了,下次请求连接池会自动帮我们重新建立连接。

当然这里有更好的解决方案,例如只关闭出问题的连接,实际上都一样(对于我的调用逻辑)

在这里插入图片描述

三 总结

在使用长链接时候是经常会出现这样的情况,记住一点: 捕获异常,主动关闭出问题的连接

以上是自己个人的片面理解,主要为了记录。如果有误或者不全欢迎指正,非常感谢🙏

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
服务器端大量的close_wait状态通常是由于服务器程序没有正确地关闭网络连接导致的。为了解决这个问题,可以采取以下几种方法: 1. 关闭连接前确保双方都关闭了连接:在服务器程序中,确保在关闭连接之前发送一个关闭请求给客户端,要求其关闭连接。这样可以避免服务器端出现大量的close_wait状态。 2. 设置合适的超时时间:在服务器程序中,为每个网络连接设置一个合适的超时时间。如果连接在超过一定时间内没有活动,那么服务器可以主动关闭连接,避免出现close_wait状态。 3. 使用连接池管理连接:通过使用连接池管理服务器和客户端之间的连接,能够更好地控制连接的创建和关闭。在每个连接使用完毕后,将其放回连接池中,而不是立即关闭。这样可以避免频繁创建和关闭连接,减少close_wait状态的产生。 4. 检查服务器程序的bug:关闭连接后产生大量的close_wait状态可能是服务器程序中存在的bug导致的。检查服务器程序的代码,确保在每个连接关闭的地方都正确处理了关闭连接的操作,避免出现资源泄漏问题。 综上所述,解决服务器端大量close_wait状态的问题需要深入分析服务器程序的代码和连接管理机制,确保连接在合适的时候被关闭,避免出现close_wait状态。同时,合理设置超时时间和使用连接池等方法也可以减少close_wait状态的产生。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值