服务器出现大量的time_wait或close wait

要明白这些先要了解TCP连接的三次握手和四次挥手:
https://blog.csdn.net/weixin_44844089/article/details/115469779

一.大量的time_wait出现

1.1 出现的原因

  • 高并发短连接的服务器上会出现这样的情况,导致创建大量的tcp连接然后close,出现大量的连接出现time_wait的状态。

1.2.大量time_wait的危害

  • 在socket的TIME_WAIT状态结束之前,该socket所占用的本地端口号将一直无法释放
  • 在高并发(每秒几万qps)并且采用短连接方式进行交互的系统中运行一段时间后,系统中就会存在大量的time_wait状态,如果time_wait状态把系统所有可用端口都占完了且尚未被系统回收时,就会出现无法向服务端创建新的socket连接的情况。此时系统几乎停转,任何链接都不能建立。
  • 大量的time_wait状态也会系统一定的fd,内存和cpu资源,当然这个量一般比较小,并不是主要危害

1.3.大量time_wait解决方案

方式一:调整系统内核参数

net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_tw_recycle = 1表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。

允许允许将TIME-WAIT sockets重新用于新的TCP连接,同时TIME-WAIT sockets的加快回收

方式二:改短连接为长连接

  • 短连接和长连接工作方式的区别:

短连接:

  • 连接->传输数据->关闭连接
  • HTTP是无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。
  • 也可以这样说:短连接是指SOCKET连接后发送后接收完数据后马上断开连接。

长连接:

  • 连接->传输数据->保持连接 -> 传输数据-> 。。。->关闭连接。
  • 长连接指建立SOCKET连接后不管是否使用都保持连接,但安全性较差。

从区别上可以看出,长连接比短连接从根本上减少了关闭连接的次数,减少了TIME_WAIT状态的产生数量,在高并发的系统中,这种方式的改动非常有效果,可以明显减少系统TIME_WAIT的数量。

二. 大量close_wait的出现

2.1 出现的原因和解决方案

  • close_wait是被动关闭连接是形成的,根据TCP状态机,服务器端收到客户端发送的FIN,TCP协议栈会自动发送ACK,链接进入close_wait状态。但如果服务器端不执行socket的close()操作(即不向客户端发送FIN),状态就不能由close_wait迁移到last_ack,则系统中会存在很多close_wait状态的连接

我觉得第一时间应该去判断是客户端的问题还是服务端的问题,有可能是客户端一直在向服务端发送FIN,也有可能是服务端一直没有发送自己的FIN。

可能的原因如下:

  • 关闭socket不及时:例如I/O线程被意外阻塞,或者I/O线程执行的用户自定义Task比例过高,导致I/O操作处理不及时,链路不能被及时释放。

通常,CLOSE_WAIT 状态在服务器停留时间很短,如果你发现大量的 CLOSE_WAIT 状态,那么就意味着被动关闭的一方没有及时发出 FIN 包,一般有如下几种可能:

  • 程序问题:如果代码层面忘记了 close 相应的 socket 连接,那么自然不会发出 FIN 包,从而导致 CLOSE_WAIT 累积;或者代码不严谨,出现死循环之类的问题,导致即便后面写了 close 也永远执行不到。
  • 响应太慢或者超时设置过小:如果连接双方不和谐,一方不耐烦直接 timeout,另一方却还在忙于耗时逻辑,就会导致 close 被延后。响应太慢是首要问题,不过换个角度看,也可能是 timeout 设置过小。
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐