深入TCP协议——tcp_tw_reuse和tcp_tw_recycle

简介: 前情提要:深入理解Linux网络——TCP协议三次握手和四次挥手详细流程我们已经知道TCP四次挥手中,主动方在收到被动方的FIN数据包之后会进入TIME_WAIT状态等待2MSL的时间后才进入CLOSED。在 Linux 操作系统下,TIME_WAIT 状态的持续时间是 60 秒,这意味着这 60 秒内,客户端一直会占用着这个端口,这是有一定的开销的。如果如果主动关闭连接方的 TIME_WAIT 状态过多,占满了所有端口资源,则会导致无法创建新连接。

前情提要:深入理解Linux网络——TCP协议三次握手和四次挥手详细流程


我们已经知道TCP四次挥手中,主动方在收到被动方的FIN数据包之后会进入TIME_WAIT状态等待2MSL的时间后才进入CLOSED。在 Linux 操作系统下,TIME_WAIT 状态的持续时间是 60 秒,这意味着这 60 秒内,客户端一直会占用着这个端口,这是有一定的开销的。如果如果主动关闭连接方的 TIME_WAIT 状态过多,占满了所有端口资源,则会导致无法创建新连接。


不过,Linux 操作系统提供了两个可以系统参数来快速回收处于 TIME_WAIT 状态的连接(这两个参数都是默认关闭的),分别是net.ipv4.tcp_tw_reuse和net.ipv4.tcp_tw_recycle。


一、tcp_tw_reuse

如果开启该选项的话,客户端 在调用 connect() 函数时,内核会随机找一个 TIME_WAIT 状态超过 1 秒的连接给新的连接复用。这其实就是相当于缩短了 TIME_WAIT 状态的持续时间。


这里既然我们缩短了TIME_WAIT状态的时间,使其不是2MSL,那么因为引入TIME_WAIT解决的问题就再次出现了,所以tcp_tw_reuse也需要解决这两个问题:


  1. 防止历史连接中的数据,被后面相同四元组的连接错误的接收
  2. 保证被动关闭连接的一方能够正确的关闭


首先看第一个问题,因为如果在历史连接上建立了新的连接,而网络中此时还有历史连接残留的数据包存活,那么它们有可能在新连接建立之后到达,那么就会导致接收到错误的数据。TIME_WAIT的解决方法就是等待2MSL之后才进入CLOSED,也就是说耗死了网络中残留的数据包,保证新连接建立时历史数据包全都死亡了。而前面我们提到了,使用tcp_tw_reuse只需要TIME_WAIT状态超过1秒就可以建立新的连接,所以它需要采用别的方式来解决这个历史数据报的问题。这里是引入了tcp_timestamps这个时间戳选项和防回绕序列号算法PAWS来解决。


防回绕序列号算法要求连接双方维护最近一次收到的数据包的时间戳(Recent TSval),每收到一个新数据包都会读取数据包中的时间戳值跟 Recent TSval 值做比较,如果发现收到的数据包中时间戳不是递增的,则表示该数据包是过期的,就会直接丢弃这个数据包。历史数据包显然时间戳必然是早于新连接建立后保存的时间戳的,所以就避免了接收旧连接残留数据的问题。


序列号本来也是递增的,正常来说延迟的数据包重新到达时序号是对不上的,因为这期间有其他新的数据包到达,会改变期待的序列号。而如果在延迟期间序列号兜了一圈又回到了原本的位置,那么延迟的数据包正好就能被正确的读取,这会导致数据错误,而时间戳保存了最近一次收到数据包的时间,所以就避免了这种情况。

即序列号会回绕,所以无法根据序列号来判断当前数据包是不是旧的数据包。


所以显然使用tcp_tw_reuse需要打开 TCP 时间戳选项,即 net.ipv4.tcp_timestamps=1(默认即为 1)。


但是其实tcp_tw_reuse还是存在风险:因为PAWS算法不会防止过期的RST,所以如果前面有残留的RST报文,在新连接建立之后到达,那么就会导致新连接被这个历史的RST包中断。如果此时不跳过 TIME_WAIT 状态,而是停留 2MSL 时长,那么这个 RST 报文就不会出现下一个新的连接。


至于第二个问题,tcp_tw_reuse并没办法解决,如果第四次挥手的 ACK 报文丢失了,而此时这个端口已经被另一个连接使用了,那么原服务端重发的FIN就会发送失败,从而接收到RST报文而异常关闭。


所以说tcp_tw_reuse还是存在风险的。


二、tcp_tw_recycle

这种机制也依赖时间戳选项,开启tcp_tw_recycel后服务器将会缓存每个套接字的最新时间戳,TIME-WAIT状态将会在超时重发(RTO)间隔后移除。不同的是tcp_tw_recycle使用的是per-host的PAWS机制,它是队对端IP做PAWS检查(tcp_tw_reuse是对四元组做PAWS检查),即Linux将会放弃所有来自远程端的timestamp时间戳小于上次记录的时间戳(也是远程端发来的)的任何数据包,除非TIME-WAIT状态已经过期**。**这个时候如果客户端网络环境是用了 NAT 网关,那么客户端环境的每一台机器通过 NAT 网关后,都会是相同的 IP 地址,在服务端看来,就好像只是在跟一个客户端打交道一样,无法区分出来(因为它是以对端IP为粒度的,而不是IP+端口)。当客户端NAT环境有多个设备,每个设备的时间肯定不会完全一致,所以访问服务端的时候,服务端观察到这个IP携带的timestamp不是单调递增的,所以会导致大量的包丢失(假如A、B机器都位于同个NAT网关下,A机器的时间要比B机器时间慢,那么当B机器发送了SYN数据包建立连接之后,A机器此时发送的SYN包就会被丢弃)。


实际上大多数情况下,都是tcp连接上的客户端主动发起fin关闭,即time_wait状态会出现在客户端,而服务端不会出现time_wait状态,这种情况服务端是不需要考虑优化回收time_wait的。但是现代的大多数应用部署在服务器上,它即会作为服务端对外提供服务,也会作为客户端去请求其他服务器上的接口,前者因为是作为服务端,很少出现time_wait状态,后者作为客户端很容易在服务器上产生大量TCP time_wait状态,我们想快速回收time_wait,主要是针对后者这种情况。此时如果我们想解决后者time_wait过多的情况,在服务器(注意是服务器,不是服务端)上开启tcp_tw_recycle快速回收端口,因为这台服务器上的应用同时又是作为服务端对外提供服务,tcp_tw_recycle触发的pre-host PAWS机制,会使得客户端超时异常。


所以net.ipv4.tcp_tw_recycle=1不能轻易开启,如果非要开启只能在以下两种场景:


  1. 并发内部调用,一般不存在客户端proxy(即客户端NAT)
  2. 自己对上下游应用有较强的可控性,可以随时调整上下游的参数一起去适配
  3. 这台服务器上的应用,只会作为客户端频繁请求其他IP(一般情况都是客户端主动关闭TCP,产生time_wait状态),没有作为服务端对外提供服务。


相关文章
|
资源调度 算法 JavaScript
Python基础专题 - 超级详细的 Random(随机)原理解析与编程实践
Python基础专题 - 超级详细的 Random(随机)原理解析与编程实践
2113 0
|
8月前
|
数据采集 人工智能 网络安全
OpenClaw-MedAgent实战指南:阿里云1分钟部署+医学文献智能检索全流程(2026版)
在医学研究与临床实践中,文献检索、数据整理与技术分析是核心环节,但传统人工方式存在效率低、信息碎片化、数据挖掘不深入等痛点。2026年,基于OpenClaw框架构建的医学文献AI助手(OpenClaw-MedAgent)应运而生,凭借模块化架构与多模型适配能力,实现医学文献自动化检索、核心原理提炼、数据资源整合与报告生成,成为医护人员、科研学者的高效工具。
1641 19
|
消息中间件 OLAP Kafka
Apache Doris 实时更新技术揭秘:为何在 OLAP 领域表现卓越?
Apache Doris 为何在 OLAP 领域表现卓越?凭借其主键模型、数据延迟、查询性能、并发处理、易用性等多方面特性的表现,在分析领域展现了独特的实时更新能力。
1037 9
|
10月前
|
传感器 Web App开发 监控
【开源免费】基于STM32+uC/OS+阿里云物联网平台的家庭安全防控系统
基于STM32与uC/OS打造的开源家庭安全系统,集成门锁控制、火焰监测、温湿度采集,通过ESP8266连接阿里云物联网平台,支持刷卡/密码开锁、远程监控与报警,OLED实时显示,安全可靠,可扩展性强,助力智能家居安防。
|
人工智能 前端开发 Java
用git rebase命令合并开发阶段中多条commit提交记录
通过 `git rebase`,可以合并多个提交记录,使开发历史更简洁清晰。操作分为 6 步:查看提交历史 (`git log --oneline`)、设置需合并的提交数 (`git rebase -i HEAD~N`)、修改动作标识为 `s`(squash)、保存退出编辑、调整提交信息、强制推送至远程仓库 (`git push -f`)。此方法适合清理本地无关提交,但若有团队协作或冲突风险,需谨慎使用以避免问题。
2946 60
|
网络协议 安全 应用服务中间件
服务器最大支持多少链接数
本文探讨了单台服务器最大支持的链接数问题,指出操作系统通过四元组(本地IP、本地端口、远程IP、远程端口)唯一标识TCP链接。链接数不仅受限于端口数量(65535),还与系统文件句柄上限、内存资源及是否绑定多个IP地址有关。通过调整系统配置和利用多IP技术,理论上可大幅提高单机支持的链接数,但实际应用中还需考虑硬件资源限制。
1318 16
|
存储 关系型数据库 MySQL
『Mysql』Mysql四种分区方式及组合分区落地实现
📣读完这篇文章里你能收获到 - Mysql分区的概念 - Mysql分区四种分区方式的落地及案例 - Mysql分区的管理
1129 0
『Mysql』Mysql四种分区方式及组合分区落地实现
|
缓存 监控 前端开发
WEB前端三大主流框架:React、Vue与Angular
在Web前端开发中,React、Vue和Angular被誉为三大主流框架。它们各自具有独特的特点和优势,为开发者提供了丰富的工具和抽象,使得构建复杂的Web应用变得更加容易。
4646 6
|
安全 网络安全 网络虚拟化
IPSec——如何快速搭建IPSec服务
IPSec——如何快速搭建IPSec服务
2229 0
|
缓存 监控 安全
在Linux中,如何排查系统崩溃问题?
在Linux中,如何排查系统崩溃问题?

热门文章

最新文章