TCP TIME_WAIT 过多怎么处理

news2024/9/25 17:21:44

文章目录

  • 1.什么是 TCP TIME_WAIT?
  • 2.为什么要 TIME_WAIT?
  • 3.TIME_WAIT 过多的影响
  • 4.解决办法
    • 4.1 调整短连接为长连接
    • 4.2 调整系统内核参数
  • 5.小结
  • 参考文献

1.什么是 TCP TIME_WAIT?

TCP 断开连接四次挥手过程中,主动断开连接的一方,在第四次挥手(回复 ACK 报文)后,会进入 TIME_WAIT 状态,等待 2*MSL 后才进入 CLOSE 状态。

在这里插入图片描述

RFC793 定义 MSL 为 2 分钟,但实际应用中常用的是30秒,1分钟和2分钟等。Linux 内核通常硬编码为 30 秒。

2.为什么要 TIME_WAIT?

这么做有两个原因:

  • 保证 ACK 重发

如果 ACK 报文丢失,被动断开连接的一方会超时重传 FIN 报文,所以需要等待 2MSL 时间处理重传的 FIN 报文,确保对方接收到确认,正常关闭连接。

  • 丢弃旧连接延迟报文

让旧连接报文从网络中消失,避免新连接收到旧连接的报文。如果不等,释放的端口可能会重新与服务器建立连接,这样依然存活在网络里的旧连接 TCP 报文可能与新连接 TCP 报文冲突,造成数据冲突。

3.TIME_WAIT 过多的影响

如果客户端(主动发起关闭连接)存在大量 TIME_WAIT 状态连接,会占用端口资源,导致新建 TCP 连接出错,报address already in use : connect异常。

如果服务端(主动发起关闭连接)存在大量 TIME_WAIT 状态连接,并不会导致端口资源受限,因为服务端只监听一个端口,而且由于一个四元组唯一确定一个 TCP 连接,因此理论上服务端可以建立很多连接。但是 TCP 连接过多,会占用系统资源,比如文件描述符、内存资源、CPU 资源、线程资源等

4.解决办法

4.1 调整短连接为长连接

比如 HTTP/1.0 请求与回包中,在 Header 中添加Connection: keep-alive

从 HTTP/1.1 开始, 就默认是开启了 keep-alive,现在大多数浏览器都默认使用 HTTP/1.1,所以 keep-alive 都是默认打开的。

如果要关闭 HTTP Keep-Alive,需要在 HTTP 请求或者响应的 header 里添加 Connection:close 信息,也就是说,只要客户端和服务端任意一方的 HTTP header 中有Connection:close信息,那就无法使用 HTTP 长连接机制。

4.2 调整系统内核参数

修改 /etc/sysctl.conf 文件中的相关配置,然后执行sysctl -p命令使配置生效。

  • 开启复用 net.ipv4.tcp_tw_reuse,默认为 0。

开启后,可以复用处于 TIME_WAIT 的 socket 为新的连接所用。

有一点需要注意的是,tcp_tw_reuse 功能只能用客户端(连接发起方),因为开启了该功能,在调用 connect() 函数时,内核会随机找一个 TIME_WAIT 状态超过 1 秒的连接给新的连接复用。

使用这个选项,还有一个前提,需要打开对 TCP 时间戳的支持,即

net.ipv4.tcp_timestamps=1(默认即为 1

这个时间戳字段在 TCP 头部的「选项」里,占用 8 个字节。其中第一个 4 字节保存发送该数据包的时间,第二个 4 字节保存最近一次接收到对方数据的时间。

由于引入了时间戳,前面提到的旧连接延迟报文问题就不复存在了,因为重复的报文会因为时间戳过期被自然丢弃。

  • 减小 net.ipv4.tcp_max_tw_buckets。

这个值默认为 18000,当系统中处于 TIME_WAIT 的连接一旦超过这个值时,新的 TIME_WAIT 连接会被立即销毁,并打印警告,这个方法比较暴力。

  • 程序中使用 SO_LINGER。

我们可以通过设置 socket 选项,来设置调用 close 关闭连接行为。

struct linger so_linger;
so_linger.l_onoff = 1;
so_linger.l_linger = 0;
setsockopt(s, SOL_SOCKET, SO_LINGER, &so_linger,sizeof(so_linger));

如果 l_onoff 为非 0, 且 l_linger 值为 0,那么调用 close 后,会立该发送一个RST标志给对端,该 TCP 连接将跳过四次挥手,也就跳过了 TIME_WAIT 状态,直接关闭。

这为跨越 TIME_WAIT 状态提供了一个可能,不过是一个非常危险的行为,不值得提倡。

5.小结

TIME_WAIT 是我们的朋友,不要试图避免这个状态,而是应该弄清楚它。

TIME_WAIT 不是 Bug,而是被设计出来的有着非常重要作用的特性,它是保证 TCP 协议可靠性不可缺失的设计。

如果过多的 TIME_WAIT 影响了系统的运行,能通过加机器解决的话就尽量加机器,如果不能解决,我们就需要理解其背后的设计原理并尽可能避免修改默认的配置。

如果服务端要避免过多的 TIME_WAIT 状态的连接,就永远不要主动断开连接,让客户端去断开,由分布在各处的客户端去承受 TIME_WAIT。

参考文献

4.1 TCP 三次握手与四次挥手面试题 - 小林coding
为什么TCP 协议有TIME_WAIT 状态 - 面向信仰编程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1430017.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计SSM基于的流浪宠物救助系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: vue mybatis Maven mysql5.7或8.0等等组成,B…

嵌入式中VMware 三种网络模式的详解与配置方法

今天梳理下 VMware虚拟机的三种网络工作模式。 相信通过这两篇文章,能够帮助你全面搞懂虚拟机的网络工作模式和配置。 VMware的三种网络工作模式 vmware为我们提供了三种网络工作模式, 它们分别是: Bridged(桥接模式)、NAT(网…

Pytest测试用例参数化

pytest.mark.parametrize(参数名1,参数名2...参数n, [(参数名1_data1,参数名2_data1...参数名n_data1),(参数名1_data2,参数名2_data2...参数名n_data2)]) 场景: 定义一个登录函数test_login,传入参数为name,password,需要用多个账号去测试登录功能 # …

八. 实战:CUDA-BEVFusion部署分析-学习spconv的优化方案(Implicit GEMM conv)

目录 前言0. 简述1. 什么是Implicit GEMM Conv2. Explicit GEMM Conv3. Implicit GEMM Conv4. Implicit GEMM Conv优化5. spconv和Implicit GEMM Conv总结下载链接参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》,链接。记录下个人学习笔记&#xff0…

量化交易学习4(投资组合基本认识)

1 如何衡量投资组合的收益率 1.1 投资组合收益率的计算方法 1.2 投资组合的绝对收益率和相对收益率 2 如何衡量投资组合的风险 2.1 风险的定义 风险是指在未来可能发生的不确定性事件所带来的潜在损失。 在投资领域中,风险通常指投资所面临的不确定性和潜在的损失…

SECS/GEM稳定可靠就用金南瓜

1、开发模式 secs协议的开发模式通常分两种: 1、完全自主开发。(开发周期长,需要secs/gem的详细协议文档,完全自主开发工作量,保守估计也要一年的工作量,还不包含工程师离职,现场测试时间&…

车企销售官网搭建流程

引言 近期在整理车企销售官网相关的一些材料时,由于之前也没接触过相关的业务,所以也是一边学习一遍整理,将自己理解官的网搭建流程给梳理出来,供与大家交流讨论。 官网搭建流程 官网搭建流程我分为两大步:网站Demo设计和网站搭建部署,具体流程如下图所示。 流程的具体…

原型中concat()-合并连接

concat() 方法主要用于连接两个或多个数组。它不会改变原有的数组,而是会返回一个包含这些数组元素的新的数组。 学习中。。。

发布3-数据库模式选择

JRT提供了Cache、IRIS、PostGreSql、人大金仓几种数据库支持。这四种数据库都可以使用,并且都有代码生成器。 对有IRIS经验的人建议的开发数据库模式是基于IRIS开发、然后用M生成导表SQL到PostGreSql和人大金仓测试,因为M调表方便,这样适应表…

Java数组的遍历

目录 数组的遍历使用for循环遍历数组使用for-each循环遍历数组使用while循环和迭代器遍历数组使用Java 8的流API遍历数组 数组遍历的应用求数组中的最大值查询数组中指定位置的元素将查指定元素对应的索引的功能提取为方法添加数组元素删除数组元素 数组的遍历 Java数组的遍历…

2024济南生物发酵展:会议日程安排和技术装备亮点预告

2024济南发酵展/2024生物发酵展/2024山东发酵展/2024济南生物制药展/2024生物技术展/2024食品设备展/2024食品加工展 由中国生物发酵产业协会主办,上海信世展览服务有限公司承办的2024第12届国际生物发酵产品与技术装备展览会(济南)将于3月5-…

【Go语言成长之路】引入外部包

文章目录 引入外部包一、查找需要引用的包二、引入需要导入的包三、运行程序 引入外部包 ​ 实现Demo: 引用rsc.io/quote包来实现打印输出 一、查找需要引用的包 ​ 比如说我现在想要找一个quote的包,那么可以通过如下步骤进行操作: 访问pkg.go.dev,并…

基于深度学习的多功能人脸识别系统

文章目录 前言一、用户登录设计二、图像采集设计1.本地视频2.摄像头3.RTSP 三、人脸识别原理1.人脸库的建立及训练2. 人脸检测算法的实现3. 人脸识别算法的实现 四、数据存储设计1.SQLite32.Excel 五、网络通信设计1.邮件通知2.阿里云 六、其他不重要功能展示1.年龄、性别和表情…

【已解决】Ubuntu64位无法运行32位ELF文件的问题

问题起因 因为在做一道逆向题,发现题目给的文件是32位elf文件,所以想在Linux下执行一下,然后发现会报错。 于是查了一下资料,发现报错的原因是64位的Ubuntu无法直接运行32位的程序,需要下载兼容32位的库。 解决方法…

单细胞scATAC-seq测序基础知识笔记

单细胞scATAC-seq测序基础知识笔记 单细胞ATAC测序前言scATAC-seq数据怎么得出的? 该笔记来源于 Costa Lab - Bioinformatics Course 另一篇关于scRNA-seq的请移步 单细胞ATAC测序前言 因为我的最终目的是scATAC-seq的数据,所以这部分只是分享下我刚学…

JavaScript鼠标事件入门

🧑‍🎓 个人主页:《爱蹦跶的大A阿》 🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 鼠标事件是Web开发中最为重要的交互方式之一。本文将带领大家入门常用…

分库分表 21 条法则,hold 住!

大家好~今天给大家分享分库分表的 21 条法则 我们结合具体业务场景,以t_order表为例进行架构优化。由于数据量已经达到亿级别,查询性能严重下降,因此我们采用了分库分表技术来处理这个问题。具体而言,我们将原本的单库…

[SWPUCTF 2021 新生赛]easyrce

经典的RCE题目看到这个eval可以想到使用系统命令执行 我们查看当前文件夹下的文件只有index.php 一般放在/目录下 我们查看 看到一个类似flag的文件 我们查看cat找到flag

顺序表和链表对应的经典算法

一,移除元素 思路:定义一个循环遍历数组,如果遇到的不是val就记录下来这个元素,如果不是就跳过 定义两个指针,一个用于保留非val元素,一个用于遍历nums int removeElement(int* nums, int numsSize, int …

基于WordPress开发微信小程序1:搭建Wordpress

2年前,在知乎上提问:多数公司为什么宁愿自研也不用wordpress二次开发建站? - 知乎 (zhihu.com),收到了,很多回答 自己打算做一下提升,便有了自己基于wordpress开发微信小程序的想法 项目定位 基于wordpre…