TIME_WAIT 简单记录(一)
作者:
| 更新日期:上周五遇到一个服务有个客户端能使用, 有的客户端不能使用的问题, 于是定位了一下.
本文首发于公众号:天空的代码世界,微信号:tiankonguse
背景
写了一个server, 发布上去, 客户端正常. 换一台客户端后, 客户端CPU跑满了, 一看监控, socket连接数也比较多.
netstat 一看, 好多 TIME_WAIT 状态.
一些数据
注:下面的ip已经随机修改, 只做参考。 另外, 目前抓到的数据不是CPU较高时候的数据。
strace 命令
监控系统调用, strace 是必选工具.
我们主要是为了统计时间浪费在哪里了, strace 的 -c
参数就有这个功能.
netstat/ss 命令
我这里曾说过, netstat 已经被ss命令和ip命令所取代.
.
那这里就使用 ss 命令了, 等价于 netstat 命令的.
我们可以只是简单的统计一下 TIME-WAIT 状态, 也可以统计所有状态的数量.
sockstat 文件
如果我们想看准确的 TIME-WAIT 数量, 还是去储存这些数据的地方看比较好.
最大端口数
我们知道. 一个 socket 连接会占用一个端口的.
那这么多的 TIME-WAIT, 会不会把可以端口使用完了呢? 看一下最大连接数吧.
看了之后, 好可怕, 总共4W端口, 但是我们的 TIME-WAIT 有35W, 所以应该端口复用了, 不是端口的问题了.
减少TIME-WAIT状态
不管怎么说, TIME-WAIT 数量很大, 我们要想办法减少 TIME-WAIT 的数量.
这里假设客户端不能修改程序, 使用短连接吧.
这里需要问一个问题: 为什么有这么多TIME-WAIT?
这个是 TCP四次挥手的知识点了, 这里不啰嗦了.
我不会告诉你4次挥手断开连接时,发起socket主动关闭的一方 socket将进入TIME_WAIT状态,TIME_WAIT状态将持续2个MSL(Max Segment Lifetime).TIME_WAIT状态下的socket一般不能被回收使用.
既然TCP加了这个功能, 那我们就可以假设TIME_WAIT是TCP协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制, 是不能缺少的.
这样的后果是 TIME-WAIT 这个状态会保存很长一段时间.
接下来我们就想能不能快速结束TIME-WAIT状态, 或者让TIME-WAIT状态不影响接下来的socket操作.
网上可以看到两个词 net.ipv4.tcp_tw_reuse
和 net.ipv4.tcp_tw_recycle
.
根据名字我们就可以知道, 一个是复用TIME-WAIT状态, 一个是回收TIME-WAIT状态.
修改操作大概如下:
注:
我未运行下面的两条命令, 所以不对执行后的结果负责.
还有人说通过sysctl命令修改内核参数时,重启后会还原
后来网上又有很多人说, 修改这两个参数后并不是万能的.
在NAT环境下会引发问题的.会引发问题的, 会引发问题的.我的网络就是NAT环境,宝宝好害怕
搜一下TIME-WAIT, 发现还有一个 tcp_max_tw_buckets 参数, 那我们是不是可以调小点这个值来变量缩小这个值呢?
这里我不做回答.
tcp_timestamps认识
背景:TCP有一种行为,可以缓存每个主机最新的时间戳,后续请求中如果时间戳小于缓存的时间戳,即视为无效,相应的数据包会被丢弃。
查看是否丢包
怎么一台有丢弃包的行为, 一台没有呢?
好吧, 原来配置的就是一台启动 tcp_timestamps, 一台没启动 tcp_timestamps.
如果关闭了tcp_timestamps, 就不会回收和重新利用TIME-WAIT了, 赶紧看看这两台机器的TIME-WAIT数量.
我能告诉你, 下面第一个是16核机器, 第二个是8核机器吗?
假设的解决方案
忽悠了这么多东西, 我现在的问题是什么呢?
问题是我写了一个server, 有些机器正常使用我的服务, 有些机器不正常使用我的服务.
那不正常的机器又什么现象呢?
CPU极度不稳定, 一会跑满, 一会降下来.
socket也是, 一会大量创建, 一会大量释放.
看看错误日志输出, 大量的connect失败.
针对这个问题, 能够命中tcp_timestamps 那个知识点.
所以我们需要做的是保证tcp_timestamps是打开的. 如果服务通过通过NAT网关的话, 确保tcp_tw_recycle关闭即可.
为什么说这个是假设的解决方案, 因为到目前为止, 我还没有解决这个问题, 只有到周一才能再次遇到这个问题, 然后才能确定真正原因是不是这个.
参考资料
- tcp_tw_recycle和tcp_timestamps导致connect失败问题
- Coping with the TCP TIME-WAIT state on busy Linux servers
- 记一次TIME_WAIT网络故障
- 发现大量的TIME_WAIT解决办法
- 再叙TIME_WAIT
- TCP的TIME_WAIT快速回收与重用
- tcp短连接TIME_WAIT问题解决方法大全(1)——高屋建瓴
- tcp短连接TIME_WAIT问题解决方法大全(2)——SO_LINGER
- tcp短连接TIME_WAIT问题解决方法大全(3)——tcp_tw_recycle
- 打开tcp_tw_recycle引起的一个问题
- tcp短连接TIME_WAIT问题解决方法大全(4)——tcp_tw_reuse
- tcp短连接TIME_WAIT问题解决方法大全(5)——tcp_max_tw_buckets
本文首发于公众号:天空的代码世界,微信号:tiankonguse
如果你想留言,可以在微信里面关注公众号进行留言。