首页 > 其他分享 >TCP TIME_WAIT 状态 及相关问题优化

TCP TIME_WAIT 状态 及相关问题优化

时间:2023-07-01 15:11:34浏览次数:43  
标签:状态 知乎 TCP TIME 连接 WAIT

TCP 是一种面向连接的可靠的传输协议,它在建立和释放连接时,需要经过一系列的握手和挥手过程。在这个过程中,会涉及到一些不同的状态,其中一个比较常见但又容易被误解的状态就是 TIME_WAIT 状态。本文将从以下几个方面介绍 TIME_WAIT 状态的原理和优化方法:

  • TIME_WAIT 状态是如何产生的?
  • TIME_WAIT 状态有什么作用和意义?
  • TIME_WAIT 状态会带来什么问题和影响?
  • 如何避免或减少 TIME_WAIT 状态的产生?

TIME_WAIT 状态是如何产生的?

要了解 TIME_WAIT 状态是如何产生的,我们首先要看一下 TCP 的状态转换图,如下所示:

 

这幅图来自 RFC 793 ,是 TCP 协议的标准文档。从这幅图中,我们可以看到,TIME_WAIT 状态主要出现在以下两种情况:

  • 当一方主动关闭连接(active close)时,它会先发送一个 FIN 包表示不再发送数据,然后等待对方的 ACK 包和 FIN 包,收到后再回复一个 ACK 包,最后进入 TIME_WAIT 状态。这种情况下,TIME_WAIT 状态持续 2 倍的 MSL(Maximum Segment Lifetime,最大报文段生存时间),然后关闭连接。MSL 是指一个 TCP 报文在网络中存在的最长时间,超过这个时间,TCP 报文就一定不会被发送到接收方。MSL 的值根据不同的网络环境而定,一般为 30 秒或 60 秒。
  • 当双方同时关闭连接(simultaneous close)时,它们都会发送一个 FIN 包表示不再发送数据,并回复对方的 FIN 包和 ACK 包,然后进入 CLOSING 状态。在 CLOSING 状态下,如果收到对方的 ACK 包,则进入 TIME_WAIT 状态。这种情况下,TIME_WAIT 状态也持续 2 倍的 MSL,然后关闭连接。

TIME_WAIT 状态有什么作用和意义?

TIME_WAIT 状态存在的目的主要有两个:

  • 防止旧连接的数据包干扰新连接。由于 TCP 连接是由四元组(源 IP 地址、源端口、目标 IP 地址、目标端口)唯一标识的,如果在一个旧连接关闭后很快建立一个新连接,并且使用相同的四元组,那么可能会出现旧连接中延迟或重传的数据包被新连接误认为是自己的数据包的情况。这样就会导致数据错乱或错误。为了防止这种情况发生,TCP 协议规定,在一个旧连接关闭后,在 2 倍 MSL 的时间内不能建立相同四元组的新连接。这样可以保证旧连接中所有可能存在的数据包都在网络中消失了。
  • 防止最后一个 ACK 包丢失导致对方重传 FIN 包。由于 TCP 协议采用了可靠传输机制,如果一个数据包没有收到对方的确认(ACK)包,那么就会认为该数据包丢失,并进行重传。在关闭连接的过程中,如果主动关闭方发送的最后一个 ACK 包丢失了,那么被动关闭方就会认为自己发送的 FIN 包丢失了,并进行重传。如果主动关闭方没有维持 TIME_WAIT 状态,那么它就无法正确地回复 ACK 包,而只能发送 RST 包表示连接已经关闭。这样被动关闭方就会认为发生了错误,而无法正常地关闭连接。为了防止这种情况发生,TCP 协议规定,在主动关闭方发送最后一个 ACK 包后,在 2 倍 MSL 的时间内维持 TIME_WAIT 状态,以便在收到对方重传的 FIN 包时能够重新发送 ACK 包。

TIME_WAIT 状态会带来什么问题和影响?

虽然 TIME_WAIT 状态有它的作用和意义,但是在一些场景下,它也会带来一些问题和影响,主要有以下几个方面:

  • 占用端口资源。由于处于 TIME_WAIT 状态的连接不能立即释放端口,而是要等待一段时间,这就会导致端口资源的浪费。如果在短时间内建立了大量的短连接,那么就可能出现端口耗尽的情况,从而无法建立新的连接。这对于一些需要高并发的应用程序来说,是一个很大的限制。
  • 占用内存资源。由于处于 TIME_WAIT 状态的连接还需要维护一些内核数据结构,比如 socket 和 TCP 控制块(TCB),这就会占用一些内存资源。如果有大量的 TIME_WAIT 状态的连接存在,那么就可能导致内存不足的情况,从而影响系统的性能和稳定性。
  • 增加 CPU 开销。由于处于 TIME_WAIT 状态的连接还需要处理一些网络事件,比如收发数据包、超时计时、状态转换等,这就会增加 CPU 的开销。如果有大量的 TIME_WAIT 状态的连接存在,那么就可能导致 CPU 负载过高的情况,从而影响系统的性能和稳定性。

如何避免或减少 TIME_WAIT 状态的产生?

针对 TIME_WAIT 状态带来的问题和影响,有以下几种可能的优化方法:

  • 让被动关闭连接的一方(服务器端或客户端)先调用 close() 函数,这样主动关闭连接的一方就不会进入 TIME_WAIT 状态,而是进入 FIN_WAIT_2 状态。这种方法需要修改应用程序的逻辑,可能不太实际。
  • 设置 SO_REUSEADDR 套接字选项,让内核允许在 TIME_WAIT 状态下重用端口。这种方法可以避免因为端口耗尽而无法建立新连接的问题,但是不能减少 TIME_WAIT 状态的数量。
  • 设置 net.ipv4.tcp_tw_reuse 或 net.ipv4.tcp_tw_recycle 参数,让内核允许在 TIME_WAIT 状态下重用或回收连接。这种方法可以减少 TIME_WAIT 状态的数量,但是可能会引起一些潜在的问题,比如与 NAT 设备或负载均衡器不兼容,或者导致旧连接的数据包干扰新连接。因此不推荐使用这种方法。
  • 设置 net.ipv4.tcp_fin_timeout 参数,调整 FIN_WAIT_2 状态的超时时间。这种方法可以缩短连接的释放过程,但是可能会导致数据丢失或错误。因此也不推荐使用这种方法。

总之,TIME_WAIT 状态是 TCP 协议为了保证可靠传输而设计的一种状态,它有它存在的必要性和合理性。在优化 TIME_WAIT 状态时,我们应该根据具体的场景和需求来选择合适的方法,并权衡其利弊。我们不应该盲目地去消除或减少 TIME_WAIT 状态,而应该温暖地看待它,并尊重它的作用和意义。

参考资料

 

 

标签:状态,知乎,TCP,TIME,连接,WAIT
From: https://www.cnblogs.com/shoshana-kong/p/17519310.html

相关文章

  • TCP协议的滑动窗口具体是怎样控制流量的?
    目录前言TCP协议概述滑动窗口的原理1发送方的滑动窗口:2接收方的滑动窗口:控制流量的机制1慢启动2拥塞避免3拥塞控制实例演示总结前言TCP协议是互联网中广泛使用的传输层协议之一,用于可靠地传输数据。其中,滑动窗口是TCP协议中用于控制流量和实现可靠传输的重要机制。本文将介......
  • MySQL批量新增或修改时出现异常: Lock wait timeout exceeded; try restarting transact
    标题:解决MySQL批量新增或修改时出现"nestedexceptionisjava.sql.SQLException:Lockwaittimeoutexceeded;tryrestartingtransaction"异常摘要在使用MySQL数据库进行批量新增或修改操作时,有时候会遇到"nestedexceptionisjava.sql.SQLException:Lockwaittimeoutexcee......
  • [问题记录] com.netflix.hystrix.exception.HystrixRuntimeException timed-out and n
    报错描述服务重启后第一次访问调用Feign接口会503,走熔断器的fallback打一次断点后再访问就没有问题,服务重启后第一次访问打断点也是503解决方案Hystrix缺省超时判断为1秒钟,由于网络问题,有些请求超过1秒钟之后才接收到增加响应时间即可hystrix:command:defau......
  • find命令mtime,ctime,atime详解
    1.查找时间说明find./-name“*data*”-mtime+1当前目录下文件名包含data,而且修改时间在48小时以上的find./-name“*date*”-mtime+2当前目录下文件名包含data,而且修改时间在72小时以上的find./name“*data*”-mtime-1当前目录下文件名包含data,而且修改时间在24......
  • Netty-TCP 01.编解码
    本文是使用Netty开发一个简单的TCP通讯(聊天)应用程序的第【1】部分,主要介绍编解码实现。定制协议一般来说,开发TCP通讯应用程序,定制通讯协议是不可避免的,这里以一种最简单的协议为例,假设一个TCP通讯数据包,包含三部分:[type][size][content]type:数据包类型(长度为一个字节,即1个by......
  • Netty-TCP 02.客户端
    本文是使用Netty开发一个简单的TCP通讯(聊天)应用程序的第【2】部分,主要介绍客户端的实现。模块划分TCP简单TCP通讯(聊天)应用程序客户端主要分为三个部分:心跳保活处理消息消费处理TCP连接实现心跳保活心跳保活是目的是告诉服务端客户端是在线的,当客户端空闲时,定时给服务端发......
  • Netty-TCP 03.服务端
    本文是使用Netty开发一个简单的TCP通讯(聊天)应用程序的第【3】部分,主要介绍服务端的实现。模块划分跟客户端类似,服务端也是主要分为三个部分:心跳检测处理消息消费处理TCP服务实现心跳检测服务端需要定时检测客户端是否在线(即是否发送心跳),如果没有,那么将客户端连接断开,同样......
  • Netty-TCP 04.发消息
    本文是使用Netty开发一个简单的TCP通讯(聊天)应用程序的第【4】部分,主要测试客户端和服务端的通讯。服务端下面是服务端测试代码:/***@authormichong*/publicclassTCPServer{publicstaticvoidmain(String[]args){TCPServerBootstrapbootstrap=ne......
  • LocalDateTime日期格式化和指定日期的时分秒
    LocalDateTime日期格式化和指定日期的时分秒packagecom.example.core.mydemo.date;importjava.time.LocalDate;importjava.time.LocalDateTime;importjava.time.format.DateTimeFormatter;/***now=2023-06-30*after=2023-07-04*afterTime=2023-07-04T00:00:0......
  • TDengine 发布 IoT 场景下 3.0 性能对比分析报告,全方位超越 InfluxDB & TimescaleDB
    6月26日,涛思数据旗下时序数据库(TimeSeriesDatabase)TDengine正式发布IoT场景下TDengine3.0性能对比分析报告,该报告在IoT场景下从数据写入、压缩和查询等维度,对比了TDengine与市场其他流行的时序数据库产品的性能差异,其中所有测试均在标准化条件下使用公开数据完成。......