服务器CLOSE_WAIT请求太多的问题

上周因为调用某个服务不可用,导致服务器出现了大量的CLOSE_WAIT的tcp链接,导致tomcat出现了假死的情况.大量的tcp请求一直卡着,其他请求进来tomcat已经不能提供服务了.
头一次遇到这样的情况,然后查了一下这个CLOSE_WAIT的资料.发现CLOSE_WAIT其实是tcp的一种状态,我们先来看张图了解一下tcp的各个状态.

状态:
CLOSED: 没有任何连接状态,是tcp状态的起点和终点(这时候服务器啥都没干)
LISTEN: 监听来自远方的TCP端口的连接请求
SYN_SENT: 第一次收到请求的状态,由客户端发送给服务端,成功后进入到SYN_RECEIVED,失败的直接CLOSED
SYN_RECEIVED:再收到和发送一个连接请求后等待对方对连接请求的确认
ESTABLISHED: 三次握手完成,已经简历一个打开的连接,这个时候就可以发送数据了
FIN_WAIT_1: 等待远程TCP连接中断请求,或先前的连接中断请求的确认
FIN_WAIT_2: 接受了远端的ACK确认之后,从等待连接中断请求
CLOSE_WAIT: 等待从本地用户发来的连接中断请求
CLOSING: 等待远程TCP对连接中断的确认
LAST_ACK: 等待原来的发向远程TCP的连接中断请求的确认
TIME_WAIT: 等待足够的时间以确保远程TCP接收到连接中断请求的确认

对照着客户端和服务端的状态变化来理解消化下

问题分析:

看完上面tcp的各个状态变化过程之后,应该有了一个大致的了解 ,给我们看下服务器上的tcp请求状态情况,可以使用命令

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

当时检测出来CLOSE_WAIT 大概有1000左右,这个和httpClient设置的maxConnTotal的数量查不多.

tcp请求关闭包含主动关闭和被动关闭,当服务端收到了中断的seq和ack后,就处于CLOSE_WAIT状态,
,照理说应该立马发送ack.但是处于CLOSE_WAIT说明服务端没有发送ack到客户端(其实这里实际上是远端服务端).导致这种情况的可能是
服务端忙于处理数据或者是其他操作,导致没有发出去ack命令.

我检查了发送请求的代码response等流都是正常关闭了,那么我们看下是不是其他问题导致,发现当接收到响应的时候,如果状态不是200,请求就直接返回了.大概类似于这样:

if (response.getStatusLine() == HttpStatus.SC_OK) {
 // 具体处理
}

如果不等于200的情况没有处理,修改后

if (response.getStatusLine() == HttpStatus.SC_OK) {
 // 具体处理
} else {
  httpRequest.abort();
 // 中断状态不对的请求
}

然后我们在etc/sysctl.conf加上如下三个参数:
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 2
net.ipv4.tcp_keepalive_time = 1800 // 单位是秒 就是30分钟

然后sysctl -p让配置生效.

1.tcp_keepalive_time
当keepalive起用的时候,TCP发送keepalive消息的频度,就是说空闲这个时间然后去确认连接是否还在,缺省是2小时。
2.tcp_keepalive_intvl
当探测没有确认时,重新发送探测的频度。缺省是75秒。
3.tcp_keepalive_probes
在认定连接失效之前,发送多少个TCP的keepalive探测包

我只做了这两个操作就CLOSE_WAIT数量就下来了,还有其他可能性也会导致这样的情况.可以参考下面的资料

参考资料:

1.https://www.cnblogs.com/jessezeng/p/5616518.html
2.https://blog.csdn.net/shootyou/article/details/6615051

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值