首要分享之前的一切文章 , 欢迎点赞保藏转发三连下次必定 >>>>
文章合集 : /post/694164…
Github : github.com/black-ant
CASE 备份 : gitee.com/antblack/ca…

一. 前言

之前在 /post/709793… 这篇文章中简单讲了一下衔接的改变 , 这一篇来看一下这个数据在实际事务中有什么效果,以及实际的案例 :

TIME_WAIT 产生的时机

TIME_WAIT 的原理和实践

TIME_WAIT 是指在 TCP 衔接封闭后,为了确保数据的牢靠传输TCP 协议需求等候一段时刻(通常是 2MSL,即两倍的最大报文段生存时刻),以确保对方接纳到了最后一个 ACK 报文段,一起也为了防止现已失效的衔接恳求报文段被传到下一个衔接中。在这段等候时刻内,TCP 衔接处于 TIME_WAIT 状况。

主要原因 : 为了防止网络中现已失效的衔接恳求报文段被传到下一个衔接中,然后导致数据的过错传输。

  • 当一个 TCP 衔接封闭后,客户端和服务端都会发送一个 FIN 报文段,表明封闭衔接。
  • 假如客户端发送的 FIN 报文段没有及时抵达服务端,而服务端现已开始封闭衔接,那么服务端将无法正确的处理客户端发送的 FIN 报文段。
  • 假如此刻有一个新的衔接恳求抵达服务端,并且该衔接的一些数据恰好和客户端发送的 FIN 报文段重复,那么就有或许会导致数据的过错传输。

处理计划: 为了防止这种情况产生,TCP 协议需求等候一段时刻,以确保对方接纳到了最后一个 ACK 报文段,一起也为了防止现已失效的衔接恳求报文段被传到下一个衔接中。因而,TIME_WAIT 是 TCP 协议为确保数据传输的牢靠性而设计的一种等候状况。

二. TIME_WAIT 基础知识

2.1 TIME_WAIT 查询方法

通常在事务中能够运用 netstat 指令来检查体系的网络衔接状况:

// 检查当前一切衔接的状况,包括 TIME_WAIT 状况
netstat -an
// 检查指定 IP 地址和端口的衔接状况
netstat -an | grep [IP]:[port]
// 检查一切状况为 TIME_WAIT 的衔接
netstat -an | grep TIME_WAIT
// 检查一切 TIME_WAIT 状况的衔接并统计数量
netstat -an | grep TIME_WAIT | wc -l

PS : netstat 指令只能提供实时的衔接信息,无法记载前史衔接信息,想要更多的前史消息,能够考虑抓包

2.2 TIME_WAIT 会和哪些问题有关

// 体系内核参数能够直接影响到 TIME_WAIT 的状况
- net.ipv4.tcp_fin_timeout : 削减 TIME_WAIT 状况的持续时刻
- net.ipv4.tcp_max_tw_buckets : 添加体系答应的 TIME_WAIT 衔接数量
// 衔接复用
- 假如没有经过衔接池等技术进行衔接池复用,则衔接的创立和封闭次数会直接影响TIME_WAIT的数量
// 应用程序衔接装备 
- 能够经过调整程序的衔接超时时刻、衔接复用机制等方法来削减衔接的创立和封闭次数
// 高并发恳求
- 恳求并发高的时分,会直接导致 TIME_WAIT 的数量,并且这种数量现已很难经过优化处理了
- 经过负载均衡等方法,能够削减 TIME_WAIT

优化 TIME_WAIT 的方法

  • 削减 TCP 衔接的树立和封闭次数,防止频频树立和封闭衔接。
  • 添加体系的最大端口号范围,确保端口号不会被用尽。
  • 调整体系的网络参数,如减小 TIME_WAIT 状况持续时刻,添加 TCP 衔接的最大数量等。
  • 运用衔接池,防止频频创立新衔接。
  • 提高硬件功能,负载均衡到多台服务器。

三. TIME_WAIT 问题实践

3.1 压测与 TIME_WAIT 的观测

  • 影响 : 压测东西通常会模仿很多的并发衔接,而由于没有衔接池等东西,导致服务器端创立很多的衔接
  • 防止 : 操控 TIME_WAIT 状况的持续时刻和重用规矩,然后缓解 TIME_WAIT 对服务器资源的占用

3.2 实践场景

这也是当时初次碰到 TIME_WAIT 的问题,当时一路搞到凌晨2-3点,终究仍是经过 TIME_WAIT 的值找到了问题。

布景 :

项目上在体系交给之前,做了一次压测,可是压测的成果一向不抱负,远远低于产品的理论值。产品会调用 LDAP (能够了解成一种树形数据库) ,MySQL 等外部特征

详细的剖析进程 :

详细的压测数据就不举例了 ,整个进程大概如下 :

// S1 : 首要我们观测的压测值,数值很低, 很不抱负
体系中在未进行优化前,会存在很多体系的瓶颈,压测的意图就是为了发现这些瓶颈,一起想办法处理他们。
// S2 : 早期我们在优化代码,尽量削减了数据库的查询
早期的处理方法主要是优化,优化了查询的处理 (其实这儿也是在削减衔接,一次查询造成的损耗是最大的)
// S3 : 后续优化衔接池计划
代码优化完成后 ,挑选的方向就是优化衔接池,经过优化衔接池的参数后,能够削减创立衔接的开销
(PS:优化 Mysql衔接后一般功能会得到很大的提高)
// S4 : 优化硬件功能
可是到了这阶段,功能其实仍是不抱负,然后挑选试着提高硬件功能。
// S5 : 发现问题
此刻就发现,无论如何提高硬件和优化衔接,压测才能都没太大提高!
推测是网络带宽是否达到了上限,进行网络排查的时分,发现TIME_WAIT 数一路飙升,当时如同挨近2// S6 : 排查方法
经过 netstat 获取后,发现一个端口在不断的创立衔接。终究进行 DEBUG 后确认由于版别问题LDAP衔接池没有生效

总结 : TIME_WAIT 假如过大,可是压测数据又没有达到正常的理论值,或许就是衔接池问题

  • 衔接池能够有效削减 TIME_WAIT 数量
  • 优化硬件对 TIME_WAIT 没有提高 (单机存在IO瓶颈,到了必定量CPU功能会下降很多)

四. 相关问题

4.1 TIME_WAIT 会占用一个随机端口数吗

什么是随机端口数?

在TCP协议中,客户端通常会运用一个随机的端口号来与服务器树立衔接。

客户端恳求服务器的IP地址和端口号,但客户端并不会指定自己运用的端口号,而是由操作体系主动分配一个闲暇的暂时端口号。

客户端运用这个随机端口号来树立衔接,服务器会将呼应数据发送到这个端口号,客户端经过这个端口号接纳服务器的呼应数据

TIME_WAIT 会占用吗?

就像之前看到的,每一个 time_wait 状况,都会占用一个「本地端口」,上限为 65535。

当衔接处在 TIME_WAIT 状况时,运用的端口号与封闭衔接前的端口号相同,不会占用其他的端口号。

在此状况下,本地端会等候两倍的MSL(Maximum Segment Lifetime,最大报文生存时刻)的时刻,这个时刻通常为几分钟,之后才会开释该端口。假如这个时分新衔接运用了这个端口,就或许出现数据紊乱或者安全问题。

4.2 TIME_WAIT 占用体系资源

或者说整个体系树立衔接的场景下,有哪些占用资源的点 :

  • 树立TCP衔接时,客户端需求指定目标服务器的IP地址和端口号,这个进程或许需求进行DNS查询和端口扫描等操作,这些操作或许会耗费一些资源
  • 短时刻内频频树立和封闭TCP 衔接 ,TIME_WAIT 状况衔接会占用体系的端口号和内存等资源,然后影响体系的功能
  • 随机端口号范围小了,引发端口号竞赛 , 暂时端口号的竞赛或许会导致TCP衔接树立失利或者衔接超时

4.3 TIME_WAIT 与衔接池的联络

运用衔接池能够有效地削减衔接的创立和封闭次数,然后削减 TIME_WAIT 状况下的衔接数量。一起,衔接池还能够经过操控衔接数量、超时时刻等参数,进一步优化衔接的运用效率。

可是,假如衔接池中存在很多的 TIME_WAIT 状况下的衔接,那么衔接池的效率或许会受到影响,然后导致体系功能下降。因而,需求经过调整衔接池的参数,如最大衔接数量、衔接超时时刻等,来防止 TIME_WAIT 问题的影响。

4.4 TIME_WAIT 与 TCP_SYNC

TCP_SYNC :攻击者使用假造的 SYN 报文不断向受害者的服务器发送衔接恳求,可是衔接并不能完成三次握手,终究服务器会不断创立半衔接,引发体系崩溃。

TIME_WAIT 的原理和实践

攻击中,攻击者会很多发送假造的 SYN 报文,但不回应服务器的 SYN+ACK 报文,然后使服务器不断等候客户端的 ACK 报文,终究导致服务器的衔接队列被占满,无法呼应正常衔接恳求。

TIME_WAIT 和 TCP_SYNC 本身没有联络,只是半衔接在必定时刻后会变成 TIME_WAIT 状况,就能够观测到 TIME_WAIT 数量增多。

总结

小知识点,说不定哪天又能够用上。