TCP TIME_WAIT状态优化

news/2024/9/24 2:28:23

一般来讲,在高并发的场景中,出现TIME_WAIT连接是正常现象,一旦四次握手连接关闭之后,这些连接也就随之被系统回收了

 

但是在实际高并发场景中,很有可能会出现这样的极端情况——大量的TIME_WAIT连接

 

TIME_WAIT状态连接过多的危害

 

  • TIME_WAIT 状态下,TCP连接占用的本地端口将一直无法释放
  • 如果TIME_WAIT连接把所有可用端口都占完了(TCP端口数量上限是65535)而且还未被系统回收,就会出现无法向服务端创建新的socket连接的情况,此时系统几乎停转,任何链接都不能建立:address already in use : connect 异常

 

相关原理

 

在遇到一个问题时,我们不但要看到其现象,更要看到问题产生背后的原理是什么,这样不但解决了问题,还能够拓展自己的知识面

 

什么是TIME_WAIT连接?

 

一般来讲,客户端(client)与服务端(server)之间的某个进程要进行通信时,在运输层层面来讲先要通过三次握手来建立TCP连接

 

TCP三次握手

 

  1. 第一次握手:客户端发送一个SYN包给服务端,然后进入到SYN_ SENT状态
  2. 第二次握手:处在监听状态的服务端收到客户端的SYN包后进行回应:发送一个ACK包给客户端,同时发送一个SYN包给客户端, 然后进入到SYN_ RCVD状态
  3. 第三次握手:客户端在收到服务端的SYN包后发送一个ACK包进行确认, 然后进入到ESTABLISHED (连接成功状态)。服务端在收到ACK包后也进入ESTABLISHED (连接成功状态)

 

通信结束后,需要关闭连接,这时候就要通过TCP的四次挥手来进行关闭连接了

 

TCP四次挥手

 

  1. 第一次挥手:客户端先发送一个FIN包给服务端,然后进入到FIN _WAIT1 (终止等待1)状态
  2. 第二次挥手:服务端收到FIN包之后对其进行回应:发送一个ACK包给客户端, 然后进入到close__ wait (关闭等待)状态。这时候服务端处于半关闭状态。
  3. 第三次挥手:同时服务端也请求关闭连接,发送一个FIN包给客户端, 然后进入LAST__ ACK (最后确认)状态
  4. 第四次挥手:客户端在收到服务端发送的ACK包之后进入到FIN__ WAIT2 (终止等待2)状态,对服务端发来的FIN包进行回应:发送一个ACK包给服务端, 然后进入到TIME__WAIT (时间等待)状态,等待2MSL (最长报文段寿命)后进入关闭状态,服务端在收到客户端发来的ACK包之后立即进入关闭状态

 

从TCP四次挥手的过程我们可以看到,主动关闭连接的一端(注意这里是说主动关闭连接的一端,即 client 和 server 都可以是主动关闭连接的一端)在收到对方的FIN包请求之后,发送ACK包进行响应,这时候会处在TIME_WAIT状态

 

为什么要有TIME_WAIT状态?

 

有很多同学可能不理解为什么会有TIME_WAIT这个状态,而且在这个状态下还要先等待2MSL(报文最大生存时间)后才真正关闭连接

 

首先,TIME_WAIT状态使得TCP全双工连接的终止更加可靠

 

我们知道,网络的本质是不可靠的,四次挥手关闭TCP连接的过程中,最后一个ACK包是由主动关闭连接一端发出的(这里我们假设是 client 进行主动关闭连接)。

 

而这个ACK有可能在路上丢失,使得处在LAST_ACK状态的一端(server端)接收不到,如果接收不到,server 就会超时重传 FIN 请求

 

所以 client 需要处在TIME_WAIT状态并等待2MSL时间来处理 server 重传的 FIN 请求,来使得 server 能够正常关闭

 

其次,TIME_WAIT状态的存在可以处理延迟到达的报文

 

网络的本质是不可靠的,也就意味着TCP报文有可能会延迟到达,TIME_WAIT状态时,两端的端口不能使用,要等到2MSL时间结束后才可以继续使用,并且在等待2MSL时间的过程中,任何迟到的报文都将被丢弃

 

这样就可以避免延迟到达的TCP报文被误认为是新TCP连接的数据,并且使得这些延迟报文在网络上消失

 

如何查看TIME_WAIT连接?

 

以我本地虚拟机(CentOS7)为例:

 

查看状态为TIME_WAIT的TCP连接

 

$ netstat -tan |grep TIME_WAIT

 

统计TCP各种状态的连接数

 

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

 

如何优化

 

 

前面我们讲过,出现一定数量的TIME_WAIT连接是正常现象,但是在线上生产环境面对高并发场景时可能会出现极端的情况——大量的TIME_WAIT连接

 

大量的TIME_WAIT连接会占用系统本地端口,导致不能再创建新的TCP连接

 

那么我们要怎么进行优化呢?

 

大量的TIME_WAIT连接存在,其本质原因是什么?

 

1.大量的短连接存在

 

在HTTP/1.0协议中默认使用短连接。

 

也就是说,浏览器和服务器每进行一次HTTP操作,就会建立一次连接,任务结束后就会断开连接,而断开连接这个请求是由server去发起的,主动关闭连接请求一端才会有TIME_WAIT状态连接

 

2.HTTP请求头里connection值被设置为close

如果HTTP请求中,connection的值被设置成close,那就相当于告诉server:server执行完HTTP请求后去主动关闭连接

 

 

优化

 

客户端层面

 

我们可以在客户端将HTTP请求头里connection的值设置为:keep-alive。将短连接改成长连接

 

长连接比短连接从根本上减少了server去主动关闭连接的次数,减少了TIME_WAIT状态连接的产生

 

(在利用nginx做反向代理时,如果要设置成长连接,则需要设置成:1.从client到nginx的连接是长连接。2.从nginx到server的连接是长连接)

 

服务器层面

我们可以通过修改服务器的系统内核参数来进行优化

 

1.允许将TIME_WAIT状态的socket重新用于新的TCP连接

 

这样的好处就是如果出现大量TIME_WAIT状态的连接,也能够将这些连接占用的端口重新用于新的TCP连接

 

$ vim /etc/sysctl.confnet.ipv4.tcp_tw_reuse = 1 #默认为0,表示关闭

 

2.快速回收TIME_WAIT状态的socket

 

$ vim /etc/sysctl.confnet.ipv4.tcp_tw_recycle = 1#默认为0,表示关闭

 

3.将MSL值缩减

 

linux中MSL的值默认为60s,我们可以通过缩减MSL值来使得主动关闭连接一端由TIME_WAIT状态到关闭状态的时间减少

 

但是这样做会导致延迟报文无法清除以及主动关闭连接一端不能收到重传来的FIN请求,也会影响很多基于TCP的应用的连接复用和调优

 

所以在实际生产环境中,需要谨慎操作

 

#查看默认的MSL值
$cat /proc/sys/net/ipv4/tcp_fin_timeout
​
#修改
$echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
​
或者
​
$ vim /etc/sysctl.conf
net.ipv4.tcp_fin_timeout = 30

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

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

相关文章

【Quant102】 经典技术指标 Pandas 实现(第一部分)

双均线策略假设你是个高级程序员和量化研究员,编写函数实现双均线策略。函数接受数据帧df,较短均线的列名称short_col和较长均线的列名称long_col,inplace参数控制是否原地更新df。买卖信号应保存在signal列中。最后返回df。def dual_moving_average_strategy(df, short_col…

2024 年 5 月 13 日 周一 晴 热(376 字)

正文感觉自己这两天摸鱼有些严重(笑。前两天有件事忘了写了。周六晚去吃饭和拍照的时候,看见有个女生坐在路边,红着眼睛跟谁打电话,语气里带一股哭腔。身上穿着校服,我想应该是高中生。身边没有人。我不知道什么事情能让人发火又哭泣,觉得有些奇怪,也不知道怎么宽慰这个…

基于高斯混合模型的视频背景提取和人员跟踪算法matlab仿真

1.算法运行效果图预览2.算法运行软件版本 MATLAB2013B3.算法理论概述基于高斯混合模型(Gaussian Mixture Model, GMM)的视频背景提取和人员跟踪算法是一种广泛应用的计算机视觉方法,主要用于分离视频序列中的静态背景和动态前景(比如人物运动)。高斯混合模型是一个概率密度函…

开发工具连接实例远程开发

远程开发主要基于将开发环境(包括代码编辑、编译、运行等)从本地机器转移到远程服务器上,这个过程涉及几个关键组件和概念远程开发主要基于将开发环境(包括代码编辑、编译、运行等)从本地机器转移到远程服务器上,这个过程涉及几个关键组件和概念: 立即免费体验:https:/…

m基于遗传优化的LDPC码OMS译码算法最优偏移参数计算和误码率matlab仿真

1.算法仿真效果 matlab2022a仿真结果如下:2.算法涉及理论知识概要低密度奇偶校验码(Low-Density Parity-Check Codes, LDPC codes)因其优秀的纠错能力和接近香农极限的性能而广泛应用于现代通信系统中。有序统计译码(Ordered Statistics Decoding, OSD)是一种基于概率译码准则…

低开开发笔记(六): 工作台与模板样式开发

好家伙,仅仅只是实现了样式,完整功能暂未完成完整代码已开源 https://github.com/Fattiger4399/ph-questionnaire.git 1.灵感来源 (抄袭对象) 刚开始想着随便写个低开项目练练手的,然后就写成这样了 1.1.简道云 1.2.问卷星 2.上代码<template><div class="docum…

vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?

一、是什么 权限是对特定资源的访问许可,所谓权限控制,也就是确保用户只能访问到被分配的资源 而前端权限归根结底是请求的发起权,请求的发起可能有下面两种形式触发页面加载触发 页面上的按钮点击触发总的来说,所有的请求发起都触发自前端路由或视图 所以我们可以从这两方…

小集训 - 3

问号这个世界就是一个巨大的问号5.11 下午 继续被 AC自动机的板题 切 感觉可能会一点 AC自动机 的dp了 然后写了 依托答辩 这小自信一下子就起来了 也一下子就下来了 (重点在时间) 淦,对着题解贺都没贺明白 😡 晚上 打 ABC 就过了 5 道 感觉 F 思路挺常规的但确实赛时不会…