记录一次 “服务器 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
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值