TCP连接TIME_WAIT

TCP断开过程:
在这里插入图片描述

TIME_WAIT的作用:

TIME_WAIT状态存在的理由:

1)可靠地实现TCP全双工连接的终止
在进行关闭连接四次挥手协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器将重发最终的FIN,
因此客户端必须维护状态信息允许它重发最终的ACK。如果不维持这个状态信息,那么客户端将响应RST分节,服务器将此分节解释成一个错误(在java中会抛出connection reset的SocketException)。
因而,要实现TCP全双工连接的正常终止,必须处理终止序列四个分节中任何一个分节的丢失情况,主动关闭的客户端必须维持状态信息进入TIME_WAIT状态。
2)允许老的重复分节在网络中消逝
TCP分节可能由于路由器异常而“迷途”,在迷途期间,TCP发送端可能因确认超时而重发这个分节,迷途的分节在路由器修复后也会被送到最终目的地,这个原来的迷途分节就称为lost duplicate。
在关闭一个TCP连接后,马上又重新建立起一个相同的IP地址和端口之间的TCP连接,后一个连接被称为前一个连接的化身(incarnation),那么有可能出现这种情况,前一个连接的迷途重复分组在前一个连接终止后出现,从而被误解成从属于新的化身。
为了避免这个情况,TCP不允许处于TIME_WAIT状态的连接启动一个新的化身,因为TIME_WAIT状态持续2MSL,就可以保证当成功建立一个TCP连接的时候,来自连接先前化身的重复分组已经在网络中消逝。

大量TIME_WAIT造成的影响:
在高并发短连接的TCP服务器上,当服务器处理完请求后立刻主动正常关闭连接。这个场景下会出现大量socket处于TIME_WAIT状态。如果客户端的并发量持续很高,此时部分客户端就会显示连接不上。
我来解释下这个场景。主动正常关闭TCP连接,都会出现TIMEWAIT。
为什么我们要关注这个高并发短连接呢?有两个方面需要注意:
高并发可以让服务器在短时间范围内同时占用大量端口,而端口有个0~65535的范围,并不是很多,刨除系统和其他服务要用的,剩下的就更少了。

在这个场景中,短连接表示“业务处理+传输数据的时间 远远小于 TIMEWAIT超时的时间”的连接。

这里有个相对长短的概念,比如取一个web页面,1秒钟的http短连接处理完业务,在关闭连接之后,这个业务用过的端口会停留在TIMEWAIT状态几分钟,而这几分钟,其他HTTP请求来临的时候是无法占用此端口的(占着茅坑不拉翔)。
单用这个业务计算服务器的利用率会发现,服务器干正经事的时间和端口(资源)被挂着无法被使用的时间的比例是 1:几百,服务器资源严重浪费。(说个题外话,从这个意义出发来考虑服务器性能调优的话,长连接业务的服务就不需要考虑TIMEWAIT状态。同时,假如你对服务器业务场景非常熟悉,你会发现,在实际业务场景中,一般长连接对应的业务的并发量并不会很高。
综合这两个方面,持续的到达一定量的高并发短连接,会使服务器因端口资源不足而拒绝为一部分客户服务。同时,这些端口都是服务器临时分配,无法用SO_REUSEADDR选项解决这个问题。

查询tcp连接数:

netstat -ant|awk '/^tcp/ {++S[$NF]} END {for(a in S) print (a,S[a])}'

命令解析:

netstat -n
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 192.168.48.2:55618      162.14.221.120:63723    ESTABLISHED
tcp        0      0 127.0.0.1:49812         127.0.0.1:30001         ESTABLISHED
tcp        0      0 192.168.48.2:443        223.104.68.23:64059     ESTABLISHED


awk '/^tcp/
滤出tcp开头的记录,屏蔽udp, socket等无关记录


NF 
表示输出的列的总数(比如:
netstat -ant|awk '/^tcp/ {print NF }'
6)


$NF
表示最后一个列(也可以定义想要的列,比如$1就是上述输出的tcp列),即输出最后一个列的内容(就是上述State列的所有内容)


S
S[]相当于定义了一个名叫S的数组


++S[$NF]
相当于把最后一列相同的计数加1(统计每个状态的数量)


END
表示在最后阶段要执行的命令


{for(a in S) print (a,S[a])}'
遍历这个S数组 并打印数组的key和value(即不同状态和对应的数量)

查询结果:

LISTEN 8
CLOSE_WAIT 1
ESTABLISHED 88
FIN_WAIT2 1
TIME_WAIT 115

状态描述:
CLOSED:无连接是活动的或正在进行
LISTEN:服务器在等待进入呼叫
SYN_RECV:一个连接请求已经到达,等待确认
SYN_SENT:应用已经开始,打开一个连接
ESTABLISHED:正常数据传输状态
FIN_WAIT1:应用说它已经完成
FIN_WAIT2:另一边已同意释放
ITMED_WAIT:等待所有分组死掉
CLOSING:两边同时尝试关闭
TIME_WAIT:另一边已初始化一个释放
LAST_ACK:等待所有分组死掉

如何尽量处理TIMEWAIT过多:

1.打开系统的TIMEWAIT重用和快速回收

1.1编辑内核文件/etc/sysctl.conf,加入以下内容:
net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout 修改系默认的 TIMEOUT 时间

然后执行 /sbin/sysctl -p 让参数生效.
/etc/sysctl.conf是一个允许改变正在运行中的Linux系统的接口,它包含一些TCP/IP堆栈和虚拟内存系统的高级选项,修改内核参数永久生效。
1.2. 
vi /etc/sysctl.conf
net.ipv4.tcp_keepalive_time = 1200
#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。
net.ipv4.ip_local_port_range = 1024 65000
#表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。
net.ipv4.tcp_max_syn_backlog = 8192
#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_tw_buckets = 5000
#表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。
默认为180000,改为5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于 Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。

2.负载均衡来抗这些高并发的短请求

参考来源

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

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

相关文章

LLM漫谈(三)| 使用Chainlit和LangChain构建文档问答的LLM应用程序

一、Chainlit介绍 Chainlit是一个开源Python包,旨在彻底改变构建和共享语言模型(LM)应用程序的方式。Chainlit可以创建用户界面(UI),类似于由OpenAI开发的ChatGPT用户界面,Chainlit可以开发类似…

虚拟机CentOS7.5编译安装Qt4.8.7

虚拟机CentOS7.5编译安装Qt4.8.7 一.下载Qt二.安装步骤 一.下载Qt 官网下载链接:Qt4.8.7 官网下载速度可能会非常慢,本人已上传至CSDN,点此下载,下载后需要先用7z软件解压成zip包。 二.安装步骤 环境安装 yum install libX11…

go语言(三)----函数

1、函数单变量返回 package mainimport "fmt"func fool(a string,b int) int {fmt.Println("a ",a)fmt.Println("b ",b)c : 100return c}func main() {c : fool("abc",555)fmt.Println("c ",c)}2、函数多变量返回 pack…

Nsis打包Unity Exe文件(通用)

Nsi 脚本 !include "MUI2.nsh"#使用现代UI Unicode true #使用Unicode !define EXENAME "exeName" #定义常量 exe名称 !define SHORTCUT "快捷方式名称" #定义桌面快捷方式的中文名称Name ${EXENAME} #安装程序的title OutFile "${EXENAME…

【C++】入门C++前想要了解的小知识

个人主页 : zxctsclrjjjcph 文章封面来自:艺术家–贤海林 如有转载请先通知 目录 1. 前言2. 什么是C3. C的发展史4. C的重要性4.1 语言的使用广泛度4.2 在工作领域中4.3 在校招领域中 5. 如何学习C5.1 看看别人怎么学习的5.2 自己怎么学 1. 前言 今天开…

FFmpeg之SwrRessample

文章目录 一、概述二、重采样流程三、重要结构体3.1、SwrContext3.2、ResamplerContext 四、重要函数4.1、swr_alloc4.2、swr_alloc_set_opts4.3、av_opt_set_*4.4、swr_init4.5、av_samples_alloc_array_and_samples4.6、av_samples_alloc4.7、swr_convert4.8、swr_get_delay4…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -投票帖子排行实现

锋哥原创的uniapp微信小程序投票系统实战: uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

【idea】idea插件编写教程,博主原创idea插件已上架idea插件市场 欢迎下载

前言:经常使用Objects.equals(a,b)方法的同学 应该或多或少都会因为粗心而传错参, 例如日常开发中 我们使用Objects.equals去比较 status(入参),statusEnum(枚举), 很容易忘记statusEnum.getCode() 或 statusEnum.getVaule() ,再比…

Java可视化物联网智慧工地综合云平台源码 私有化部署

智慧工地平台围绕建筑施工人、物、事的安全管理为核心,对应研发了劳务实名制、视频监控、扬尘监测、起重机械安全监测、安全帽监测等功能一体化管理的解决方案。 智慧工地是聚焦工程施工现场,紧紧围绕人、机、料、法、环等关键要素,综合运用…

docker安装运行CloudBeaver并设置默认语言为中文

1、CloudBeaver CloudBeaver 是一个开源的 Web 数据库管理工具,它提供了一个基于浏览器的用户界面,允许用户管理和操作各种类型的数据库。CloudBeaver 支持多种数据库系统,包括但不限于 PostgreSQL、MySQL、SQLite、Oracle、SQL Server 以及…

RabbitMQ入门精讲

1. 什么是消息队列 消息指的是两个应用间传递的数据。数据的类型有很多种形式,可能只包含文本字符串,也可能包含嵌入对象。 “消息队列(Message Queue)”是在消息的传输过程中保存消息的容器。在消息队列中,通常有生产者和消费者两个角色。…

【Java基础_01】Java运行机制及运行过程

【Java基础_01】Java运行机制及运行过程 文章目录 【Java基础_01】Java运行机制及运行过程1.Java 运行机制及运行过程1.1 Java 核心机制-Java 虚拟机 [JVM java virtual machine] 1.2 JDK,JRE1.3 JVM,JDK和JRE1.4 环境变量path1.4.1 为什么要配置path1.4.2 配置环…

【一步一步学】ROS软路由设置代理IP教程

申明:本文仅针对国内L2TP/PPTP,适用于国内的游戏加速或学术研究,禁止一切利用该技术的翻墙行为。 今天和大家分享的是ROS软路由如何设置分流的问题,很多做过工作室的小伙伴肯定很熟悉。 简单来讲,ROS软路由就是普通的路…

数模转换 120dB,192kHz DAC 音频转换芯片DP7398 软硬件兼容替代CS4398

数模转换芯片(DAC)是一种将数字信号转换为模拟信号的集成电路。它通过将数字数据转换为相应的模拟电压或电流输出,实现了数字系统与模拟系统之间的接口和互联。 DAC具有许多优势,使其在各种应用领域得到广泛应用。首先&#xff0c…

接口测试 01 -- 基础与原理

接口概述 什么是接口 接口是计算机系统中不同组件之间进行交流和互动的一种方式。 在软件开发中,接口通常指的是一组定义了输入、输出、功能和规范的方法、函数或协议。接口定义了组件之间的通信协议,使得它们可以相互协作,实现特定的功能。…

23.实战演练--个人主页

<?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"><applicationandroid:allowBackup"true"an…

【latex】参考文献排版前移,在最前面引用\usepackage{url}

【LaTeX】参考文献排版前移&#xff0c;在最前面引用\usepackage{url} 写在最前面完整解决步骤请教申申latex编译报错解决方案 写在最前面 参考文献从21开始排版前移了 解决方案&#xff1a;在最前面加一行 \usepackage{url}完整解决步骤 请教申申 申申yyds&#xff01;&am…

VsCode插件开发之ChatGPT实战

基础介绍&#x1f5e3;︎ VSCode 是采用了 Electron开发的跨平台的桌面应用&#xff0c;它兼容 Mac、Windows 和Linux&#xff0c;可以构建出三个平台的应用程序&#xff0c;基于VSCode开发的插件&#xff0c;同样也能在多个平台同时运行。 VSCode布局&#xff1a; 插件开发&…

IDEA插件中的postman,你试试

Postman是大家最常用的API调试工具&#xff0c;那么有没有一种方法可以不用手动写入接口到Postman&#xff0c;即可进行接口调试操作&#xff1f;今天给大家推荐一款IDEA插件&#xff1a;Apipost Helper&#xff0c;写完代码就可以调试接口并一键生成接口文档&#xff01;而且还…

JAVA方法及练习

目录 Java方法的定义以及调用 带返回值方法的定义和调用 方法的重载 方法大练习 练习1 练习2 练习3 练习4 Java方法的定义以及调用 方法练习package java方法;public class fangfa1 {public static void main(String[] args) {xuexi();}//定义一个方法public static vo…