TCP TIME_WAIT 过多怎么处理

文章目录

  • 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 状态 - 面向信仰编程

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ctfshow——文件包含

文章目录 web 78——php伪协议第一种方法——php://input第二种方法——data://text/plain第三种方法——远程包含(http://协议) web 78——str_replace过滤字符php第一种方法——远程包含(http://协议)第二种方法——data://&…

游戏被DDOS攻击无法访问时该如何处理

游戏行业随着时代的发展有着突飞猛进的变化,尤其是互联网时代智能手机的普及,让游戏行业发展上了一个新的台阶。因为游戏带来的巨大利润,游戏行业一直是DDoS攻击的首选目标。 DDoS是Distributed Denial of Service的缩写,即分布式…

学习Android的第二天

目录 Android User Interface 用户界面 UI Android View与ViewGroup的概念 Android View android.view.View android.view.View XML 属性 android:id 属性 Android ViewGroup android.view.ViewGroup ViewGroup.LayoutParams ViewGroup.MarginLayoutParams ViewGr…

Redis核心技术与实战【学习笔记】 - 19.Pika:基于SSD实现大容量“Redis”

前言 随着业务数据的增加(比如电商业务中,随着用户规模和商品数量的增加),就需要 Redis 能保存更多的数据。你可能会想到使用 Redis 切片集群,把数据分散保存到不同的实例上。但是这样做的话,如果要保存的…

java社区养老年人服务系统springboot+vue

为了帮助用户更好的了解和理解程序的开发流程与相关内容,本文将通过六个章节进行内容阐述。 第一章:描述了程序的开发背景,程序运用于现实生活的目的与意义,以及程序文档的结构安排信息; 第二章:描述了程序…

uniapp 高德地图显示

1. uniapp 高德地图显示 使用前需到**高德开放平台(https://lbs.amap.com/)**创建应用并申请Key   登录 高德开放平台,进入“控制台”,如果没有注册账号请先根据页面提示注册账号   打开 “应用管理” -> “我的应用”页面…

Leetcode 85. 最大矩形

题目信息 LeetoCode地址: 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 题目理解 该题是84题的升级版。84题给出了一个一维数组,即一行数据,每个元素是高度。而该题则是给出了二维数组,只需我们将每一行的高度…

太强了,AI数字人从制作到变现一次搞定

AI数字人从制作到变现 如果说GPT类大模型是我们人类的第二大脑,数字人就是我们人类在互联网上的第二个身体。随着 AI 的迅速发展,2024 年 AI 模型开始从大型语言模型向大型视觉模型转变。数字人技术作为其分支之一,正日益成为科技、娱乐、教…

【GAMES101】Lecture 14 15 辐射度量学

目录 辐射度量学 Radiant flux(光通量) intensity(发光强度) irradiance radiance 辐射度量学 主要讲述了物理学中的Basic radiometry (辐射度量学),就是我们在之前的计算光照中没有用具体的物理单位去衡量和描述…

C++新特性 协程

本篇文章我们来讲述一下C协程 协程(Coroutine)是一种能够挂起个恢复的函数过程 是一种轻量级的并发编程方式,也称为用户级线程。它与传统的线程(Thread)相比,具有更低的开销和更高的执行效率。 协程通常运…

爬虫学习笔记-scrapy爬取汽车之家

1.终端运行scrapy startproject scrapy_carhome,创建项目 2.接口查找 3.终端cd到spiders,cd scrapy_carhome/scrapy_carhome/spiders,运行 scrapy genspider audi https://car.autohome.com.cn/price/brand-33.html 4.打开audi,编写代码,xpath获取页面车型价格列表 5.运行项目…

深度学习技巧应用35-L1正则化和L2正则在神经网络模型训练中的应用

大家好,我是微学AI,今天给大家介绍一下深度学习技巧应用35-L1 正则化和L2正则在神经网络模型训练中的应用。L1正则化和L2正则化是机器学习中常用的两种正则化方法,用于防止模型过拟合并提高模型的泛化能力。这两种正则化方法通过在损失函数中添加惩罚项来控制模型的复杂性。…

面试八股文(4)

文章目录 1.sleep和wait区别2.为什么调用start()方法会执行run()方法,为什么不能直接调用run()方法3.synchronized关键字4.并发编程的三个重要特性5.synchronized和volatile关键字区别6.ThreadLocal7.为什么要用线程池?8.实现Runnable接口和Callable接口…

课时13:变量基础_变量场景

2.1.1 变量场景 学习目标 这一节, 我们从 数据存储、变量场景、小结 三个方面来学习。 数据存储 数据存储 所谓的数据存储,我们从三方面来理解这句话:1、数据保存到哪里 -- 各种媒介,CPU、内存、磁盘、磁带、网盘...2、数据保…

react+ts+antd-mobile 动态tabs➕下拉加载

1.初始化项目 //搭建项目 npm create vitelatest react-jike-mobile -- --template react-ts//安装依赖 npm i //运行 npm run dev清理项目目录结构 安装ant design mobile ant design mobile是ant design家族里专门针对于移动端的组件库 npm install --save antd-mobile测试…

日志报错 git -c dif.mnemonicprefix=false -c core.guotepath=false 解决方法

前言: 在进行下面操作前,必须确保,你是否安装了Git。 查看Git 在命令行窗口中输入`git --version`: 如果这个命令成功显示了Git的版本信息,这表明Git已经被安装。 1. 使用Sourcetree SourceTree 是 Windows 和Mac OS X 下免费的 Git 和 Hg 客户端…

C++核心deque容器,stack容器,queue容器,list容器,set容器,pair ,map容器

3.deque容器 1.deque容器的基本概念 Vector容器是单向开口的连续内存空间,deque则是一种双向开口的连续线性空间。所谓的双向开口,意思是可以在头尾两端插入元素,但是在其头部操作效率奇差,无法被接受。 deque容器和vector容器最…

MongoDB索引详情

文章目录 MongoDB索引MongoDB索引数据结构WiredTiger数据文件在磁盘的存储结构 索引的分类索引设计原则索引操作创建索引查看索引删除索引 索引类型单键索引(Single Field Indexes)复合索引(Compound Index)多键索引(M…

学成在线:采用XXL-JOB任务调度方案使用FFmpeg处理视频转码业务

分片技术方案 概述 XXL-JOB并不直接提供数据处理的功能,它只会给所有注册的执行器分配好分片序号,在向执行器下发任务调度的同时携带分片总数和当前分片序号等参数 设计作业分片方案保证多个执行器之间不会查询到重复的任务,保证任务不会重复执行 任…

机器学习-基础分类算法-KNN详解

KNN-k近邻算法 k-Nearest Neighbors 思想极度简单应用数学只是少效果好可以解释机器学习算法使用过程中的很多细节问题更完整的刻画机器学习应用的流程 创建简单测试用例 import numpy as np import matplotlib.pyplot as plt raw_data_X [[3.393533211, 2.331273381],[3.1…