365被限制了让提款-365提款-28365365体育在线投注

TIME_WAIT详解与优化

TIME_WAIT详解与优化

1、TIME_WAIT状态概述

TIME_WAIT,也称为 2MSL 等待状态,是 TCP 连接终止过程中的一个阶段。当一方主动关闭连接后,会进入 TIME_WAIT 状态,并保持该状态 2 倍的最大报文段生命周期(MSL)。默认情况下,MSL 为 2 分钟,因此 TIME_WAIT 通常持续 4 分钟。

这个状态的目的是确保:

对方收到连接终止的确认(ACK)。延迟到达的任何数据包被丢弃,而不是被后续连接错误地接收。附:MSL 时间,Maximum Segment Lifetime,即“报文最大生存时间”。任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。(IP 报文)TCP报文 (segment)是ip数据报(datagram)的数据部分。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。2MSL,TCP 的 TIME_WAIT 状态,也称为2MSL等待状态:当TCP的一端发起主动关闭(收到 FIN 请求),在发出最后一个ACK 响应后,即第3次握手完成后,发送了第四次握手的ACK包后,就进入了TIME_WAIT状态。必须在此状态上停留两倍的MSL时间,等待2MSL时间主要目的是怕最后一个 ACK包对方没收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后,可以再发一个ACK应答包。在 TIME_WAIT 状态时,两端的端口不能使用,要等到2MSL时间结束,才可继续使用。(IP 层)

不过在实际应用中,可以通过设置 「SO_REUSEADDR选项」,达到不必等待2MSL时间结束,即可使用被占用的端口

2、TIME_WAIT形成的原因?

TIME_WAIT是 TCP 连接关闭时的一个状态。系统出现大量TIME_WAIT状态的连接,主要有以下原因:

1)高并发短连接应用

一些高并发的网络应用,如 Web 服务器、微服务架构中的服务节点等,通常采用短连接的方式处理大量客户端请求。当客户端与服务器完成一次数据交互后,连接就会被关闭,此时连接会进入TIME_WAIT状态。如果这类应用的并发量很高,就会导致系统中出现大量处于TIME_WAIT状态的连接。

2)端口释放机制

在 TCP 连接中,主动关闭连接的一方会进入TIME_WAIT状态,并在该状态停留一段时间(通常为 2 倍的 MSL,即最长报文段寿命)。这是为了确保最后一个 ACK 报文能够被对方正确接收,同时也是为了让网络中可能存在的旧数据包自然消亡,避免新连接复用端口时出现混淆。如果系统中频繁出现主动关闭连接的情况,就会导致大量连接处于TIME_WAIT状态。

3)网络延迟和丢包

网络延迟或丢包可能导致连接关闭过程出现异常。例如,当一方发送了 FIN 报文后,由于网络问题,对方未能及时收到,那么发送方就会一直等待对方的 ACK,从而使连接长时间处于TIME_WAIT状态。另外,如果在TIME_WAIT状态下,ACK 报文丢失,发送 FIN 的一方也会重新发送 FIN,导致TIME_WAIT状态延长,进一步增加了处于该状态的连接数量。

4)应用程序设计不合理

某些应用程序在使用完网络连接后,没有及时关闭连接,或者没有正确处理连接关闭的逻辑,导致连接不能正常释放,进而进入TIME_WAIT状态。此外,如果应用程序中存在大量短时间内频繁创建和销毁连接的操作,也会导致系统中TIME_WAIT状态的连接增多。

5)SYN 攻击

攻击者向目标系统发送大量伪造的 SYN 报文,请求建立 TCP 连接,但不完成连接的三次握手过程。目标系统为了响应这些请求,会分配资源并进入SYN_RECV状态,随后在一段时间后会将这些半连接关闭,进入TIME_WAIT状态。如果攻击者发送的 SYN 报文数量足够多,就会导致系统中出现大量处于TIME_WAIT状态的连接,耗尽系统资源,影响正常的网络服务。

3、TIME_WAIT状态核心问题

1)time_wait 是「服务器端」的状态?or 「客户端」的状态?

time_wait 是「主动关闭 TCP 连接」一方的状态,可能是「客服端」的,也可能是「服务器端」的,一般情况下,都是「客户端」所处的状态;「服务器端」一般设置「不主动关闭连接」。

2)服务器在对外服务时,是「客户端」发起的断开连接?还是「服务器」发起的断开连接?

正常情况下,都是「客户端」发起的断开连接,「服务器」一般设置为「不主动关闭连接」,服务器通常执行「被动关闭」,但 HTTP 请求中,http 头部 connection 参数,可能设置为 close,则,服务端处理完请求会主动关闭 TCP 连接。

3)关于 HTTP 请求中,设置的主动关闭 TCP 连接的机制:TIME_WAIT的是主动断开方才会出现的,所以主动断开方是服务端?

是的。在HTTP1.1协议中,有个 Connection 头,Connection有两个值,close和keep-alive,这个头就相当于客户端告诉服务端,服务端执行完成请求之后,是关闭连接还是保持连接,保持连接就意味着在保持连接期间,只能由客户端主动断开连接。还有一个keep-alive的头,设置的值就代表了服务端保持连接保持多久。HTTP默认的Connection值为close,那么就意味着关闭请求的一方几乎都会是由服务端这边发起的。那么这个服务端产生TIME_WAIT过多的情况就很正常了。虽然HTTP默认Connection值为close,但是,现在的浏览器发送请求的时候一般都会设置Connection为keep-alive,等待客户端主动断开连接。所以,大部分情况下没有必要通过调整参数来减少TIME_WAIT连接。

4、TIME_WAIT状态的连接会占用哪些系统资源吗?

内存资源

系统需要为每个TIME_WAIT状态的连接维护相关的控制块信息,包括连接的四元组(源 IP、源端口、目的 IP、目的端口)、定时器信息以及一些协议相关的状态标志等。这些信息都需要占用一定的内存空间,当TIME_WAIT连接数量较多时,会消耗大量的内存资源。

文件描述符资源

在操作系统中,每个网络连接都需要占用一个文件描述符来进行数据的读写操作。处于TIME_WAIT状态的连接虽然已经不再进行数据传输,但仍然占用着文件描述符资源,直到超时结束。如果系统中TIME_WAIT连接过多,可能会导致文件描述符资源被耗尽,从而影响新连接的建立。

端口资源

在 TCP 协议中,源端口和目的端口是标识连接的重要组成部分。处于TIME_WAIT状态的连接会占用源端口,在TIME_WAIT超时期间,该端口不能被其他连接复用。这可能会导致可用端口资源减少,尤其是在高并发场景下,当大量连接处于TIME_WAIT状态时,可能会出现端口耗尽的情况,进而影响系统的性能和可用性。

5、TIME_WAIT 与端口范围的关系

1)端口范围的定义

临时端口(Ephemeral Ports):客户端发起连接时使用的动态端口。

默认范围:

Linux:32768-60999(由 /proc/sys/net/ipv4/ip_local_port_range 定义)。

Windows:49152-65535。

2)TIME_WAIT 对端口的影响

占用四元组:TIME_WAIT 状态的连接会占用 源IP:源端口:目标IP:目标端口 的组合。

端口耗尽风险:

在高并发短连接场景(如频繁调用 HTTP API),大量端口处于 TIME_WAIT 状态。

当可用端口耗尽时,新连接会因无法分配端口而失败,报错 Cannot assign requested address。

3)数学关系

最大理论并发连接数 = (可用端口数量) × (目标 IP 数) × (目标端口数)。

若目标固定(如单台服务器),最大并发受限于可用端口数 × 目标端口数。

6、如何减少TIME_WAIT状态的连接数量?

要减少系统中TIME_WAIT状态的连接数量,可以从调整系统参数、优化应用程序设计、改进网络配置等多个方面入手。以下是具体的解决方案:

1)调整系统参数(Linux 系统)

启用 TCP 时间戳(TCP Timestamps)

允许系统复用处于TIME_WAIT状态的端口,缩短等待时间。

# 永久生效:编辑 /etc/sysctl.conf,添加或修改以下行

net.ipv4.tcp_timestamps = 1 # 启用时间戳(默认已启用)

net.ipv4.tcp_tw_reuse = 1 # 允许复用TIME_WAIT连接

net.ipv4.tcp_tw_recycle = 1 # 快速回收TIME_WAIT连接(谨慎使用)

# 立即生效

sysctl -p

缩短 TIME_WAIT 超时时间

减少TIME_WAIT状态的持续时间(默认 2MSL≈120 秒)。

# 编辑 /etc/sysctl.conf

net.ipv4.tcp_fin_timeout = 30 # 将超时时间缩短为30秒

# 立即生效

sysctl -p

增加可用端口范围

扩大系统可用的临时端口范围,减少端口资源耗尽的风险。

# 编辑 /etc/sysctl.conf

net.ipv4.ip_local_port_range = 10000 65535 # 扩大临时端口范围

# 立即生效

sysctl -p

启用端口复用(SO_REUSEADDR/SO_REUSEPORT)

允许新连接重用处于 TIME_WAIT 状态的端口:

# 开启端口复用

echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse

# 永久生效

echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf

sysctl -p

2)优化应用程序设计

使用长连接代替短连接

对于频繁通信的服务,采用长连接(如 HTTP/2、gRPC)减少连接创建 / 销毁。示例:在 Go 语言中使用http.Client时设置长连接:

client := &http.Client{

Transport: &http.Transport{

MaxIdleConns: 100,

MaxIdleConnsPerHost: 10,

},

}

优化连接关闭逻辑

避免频繁主动关闭连接,让客户端而非服务端主动关闭连接。使用连接池复用现有连接(如数据库连接池、HTTP 连接池)。

负载均衡与集群化

通过负载均衡器(如 Nginx、HAProxy)分散流量,减少单个服务器的连接压力。

使用反向代理 / 负载均衡器

将长连接保持在负载均衡器层,后端服务使用短连接,减少服务端的TIME_WAIT。

3)监控与告警

监控 TIME_WAIT 连接数量

# 统计TIME_WAIT连接数量

netstat -an | grep TIME_WAIT | wc -l

# 查看哪些IP产生最多TIME_WAIT

netstat -anp | grep TIME_WAIT | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr

设置告警阈值

当TIME_WAIT连接数量超过阈值时触发告警,及时排查问题。

4)特殊场景处理

高并发短连接服务(如 API 网关)

优先使用tcp_tw_reuse和tcp_timestamps。考虑使用 UDP 协议(如果业务允许)。

反向代理服务器(如 Nginx)

# nginx.conf 配置示例

http {

keepalive_timeout 65; # 保持长连接超时时间

keepalive_requests 100; # 每个连接允许的最大请求数

tcp_nodelay on; # 禁用Nagle算法

}

5)注意事项

谨慎使用 tcp_tw_recycle

该参数在 NAT 环境下可能导致连接中断(RFC1323 要求两端都支持时间戳)。Linux 内核 4.12 及以上版本已移除该参数。

性能与稳定性平衡

缩短TIME_WAIT超时时间可能增加数据包混淆风险。增加系统参数值需考虑服务器内存和网络带宽限制。

根本解决方案:

优化应用架构(如微服务间使用长连接)比调整系统参数更有效。

7、场景验证

验证端口耗尽

# 查看当前 TIME_WAIT 连接数

ss -tan | grep TIME-WAIT | wc -l

# 查看临时端口使用情况

cat /proc/sys/net/ipv4/ip_local_port_range

模拟端口耗尽

# 使用压测工具快速创建短连接

ab -n 100000 -c 1000 http://target-server/