time_wait详解

什么是time_wait

我们知道TCP的需要三次握手建立连接,四次挥手断开连接。在建立和断开TCP连接的过程中,客户端和服务端会经历各种类型状态,如下图所示:

其中有一个状态就是TIME_WAIT,当主动关闭连接的一方收到被动关闭一方发来的FIN并返回ACLK报文后进入该状态。

TIME_WAIT状态又称之为2MSL状态。每个TCP连接都有一个最大保温段生存时间MSL,TIME_WAIT状态持续时间为2MSL。

设置该状态有什么作用呢?作用主要有两个:

  1. 让当前连接中所有报文分组在网络中消逝,防止干扰下一次连接;
  2. 保证TCP全双工连接的正确关闭。因为主动关闭一方回复的ACK报文可能丢失,如果立即关闭,被动关闭一方没收到ACK报文,就会一直发送FIN报文,无法正常关闭。

time_wait带来的问题

TIME_WAIT状态可以保证TCP可以正确建立连接并断开,但是持续2MSL时间也会给系统带来一些问题。即系统中可能存在大量处于TIME_WAIT状态的连接,导致无法建立新连接。因为TCP本地端口数量上限为65535,当大量连接处于该状态时,新建TCP连接会报错address already in use: connect

查看TCP连接状态

Linux下主要通过netstat命令查看网络相关状态信息,其使用方式如下:

1
2
3
4
5
6
7
8
○ 命令:netstat
○ 参数:
-a (all)显示所有选项,默认不显示LISTEN相关
-p 显示建立相关链接的程序名
-n 拒绝显示别名,能显示数字的全部转化成数字。
-t (tcp)仅显示tcp相关选项
-u (udp)仅显示udp相关选项
-l 仅列出有在 Listen (监听) 的服务状态

我们可以通过如下命令查看系统tcp连接数及状态:

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

为什么产生大量time_wait状态连接

为什么会产生大量time_wait状态呢?

  • 大量的短连接存在,即高并发短链接
  • 特别是 HTTP 请求中,如果 connection 头部取值被设置为 close 时,基本都由「服务端」发起主动关闭连接

HTTP 头部字段Connection有啥用?

在http请求时,我们一般会在request header 或 response header 中看到”Connection:Keep-Alive”或 “Connection:close”,这里具体的含义是有关http 请求的是否保持长连接,即链接是否复用,每次请求是复用已建立好的请求,还是重新建立一个新的请求。

如果链接不复用,都是短连接的话,并发过高的情况下,会直接把服务器的连接数打满导致无法建立新连接。

怎么解决该问题

常见的解决方法有:

  • 服务端
    • 允许 time_wait 状态的 socket 被重用
    • 缩减 time_wait 时间,设置为 1 MSL(即,2 mins)
    • 不允许主动关闭连接
  • 客户端
    • HTTP 请求的头部,connection 设置为 keep-alive,保持存活一段时间。现在的浏览器,一般都这么进行了。
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2022 Yin Peng
  • 引擎: Hexo   |  主题:修改自 Ayer
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信