• 对于注定会优秀的人来说,他所需要的,只是时间!
  • 手懒得,必受贫穷,手勤的,必得富足----《圣经》
  • 帮助别人,成就自己。愿君在本站能真正有所收获!
  • 如果你在本站中发现任何问题,欢迎留言指正!
  • 宝剑锋从磨砺出,梅花香自苦寒来!

CentOS系统里TCP状态中TIME_WAIT超过3万的分析与建议

迎刃而解 eryajf 6个月前 (03-25) 750°C 已收录 0个评论
本文预计阅读时间 4 分钟
文章目录[隐藏]

通过如下命令,我们可以看到系统当中TCP状态中的情况:

$ netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

LAST_ACK     192
SYN_RECV     97
CLOSE_WAIT   2
ESTABLISHED      14418
FIN_WAIT1    389
FIN_WAIT2    1706
SYN_SENT     2
CLOSING      51
TIME_WAIT    17697

当然了,如果我们配置了系统监控,那么从Prometheus中看系统TCP状态会更加清晰。

主机上的TCP状态的TIME_WAIT数非常高,在三万到五万之间徘徊,这是相当高的,在分析问题原因以及给出解决方案之前,先来理解一下这个TIME_WAIT是个什么东东。

定义

我们的应用对外提供服务,当 TCP 连接主动关闭时,都会经过 TIME_WAIT 状态。TCP 四次握手结束后,连接双方都不再交换消息,但主动关闭的一方会保持这个连接在一段时间内不可用。

分析

那么,保持这么一个状态有什么用呢?

为了理解 TIME_WAIT 状态的必要性,我们先来假设没有这么一种状态会导致的问题。暂以 A、B 来代指 TCP 连接的两端,A 为主动关闭的一端。

  • 四次挥手中,A 发 FIN, B 响应 ACK,B 再发 FIN,A 响应 ACK 实现连接的关闭。而如果 A 响应的 ACK 包丢失,B 会以为 A 没有收到自己的关闭请求,然后会重试向 A 再发 FIN 包。

此时,如果没有 TIME_WAIT 状态,A 不再保存这个连接的信息,收到一个不存在的连接的包,A 会响应 RST 包,导致 B 端异常响应。

此时, TIME_WAIT 是为了保证全双工的 TCP 连接正常终止。

我们还知道,TCP 下的 IP 层协议是无法保证包传输的先后顺序的。如果双方挥手之后,一个网络四元组(src/dst ip/port)被回收,而此时网络中还有一个迟到的数据包没有被 B 接收,A 应用程序又立刻使用了同样的四元组再创建了一个新的连接后,这个迟到的数据包才到达 B,那么这个数据包就会让 B 以为是 A 刚发过来的。

解决

从如上内容的分析中,我们在解决此类问题的时候,大致有两个方向可走,一个是控制一个TCP连接流程在系统当中的最大时间,一个是分配的time_wait容量池的最大容量,从这两个角度入手,一般就能比较好的控制系统当中time_wait的数量。

而上边说到的这两个参数,则都是在内核参数当中进行配置定义的。在sysctl.conf当中定义如下参数:

net.ipv4.tcp_fin_timeout = 20 # 设置单条TCP超时时间为20s,centos中默认为30s
net.ipv4.tcp_max_tw_buckets = 19400

在网上一些文章中,有建议将 net.ipv4.tcp_max_tw_buckets这个参数往大了调的,这种建议呢,或许在业务量小,没跑出系统性能的情况下,是合适的,但是如果在业务量庞大的场景下,我是不建议使劲儿把这个参数往大了调的,如果设置的过大(超过常规的65535),那么很可能会影响正常的TCP请求,因此应该自行斟酌将此值设置在一个合理的范围当中。


weinxin
扫码订阅本站,第一时间获得更新
微信扫描二维码,订阅我们网站的动态,另外不定时发送WordPress小技巧,你可以随时退订,欢迎订阅哦~

二丫讲梵 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明CentOS系统里TCP状态中TIME_WAIT超过3万的分析与建议
喜欢 (0)
[如果想支持本站,可支付宝赞助]
分享 (0)
eryajf
关于作者:
学无止境,我愿意无止境学。书山有路,我愿意举身投火,淬炼成金!永远不要忘记,激情的奋进,就是美好的未来!

您必须 登录 才能发表评论!