TCP三次握手没回第一个SYN包

作者: | 更新日期:

问题很难,也很简单。

本文首发于公众号:天空的代码世界,微信号:tiankonguse

一、背景

最近几年流行把服务搬到云上去。
这不,一个业务搬到云上后,读我的服务时发生了异常,便找过来了。

二、沟通

我根据自己的了解,回答了致命的一句:云上与公司网络本来就是不通的。
云的负责人回答说本来是不通的,为了上云,他们搞了一个VPC网络,然后和公司网络打通了。

既然想测试网络是否同,我就推荐了一些常用的方法: ping 一下或者 telnet 服务端的端口。
对方回答没发登录云上的容器。

最终只能让客户端告诉我他的来源IP,然后我去对应的机器上抓包了。

三、网络是通的

tcpdump 抓了一个包一看,发现三次握手,以及收发数据都是正常的。
我回答网络没问题,正常通信了,完事。
对方回答,单次请求一直都是可以的,是偶先失败。

原来上面沟通与定位那么久,都是无用功了。

回头看看沟通的第一句话,他们只是说拉我的服务存在异常失败,但是没说是不是部分失败。
而我的历史经验是网络不通的,大家就又开始定位是不是网络不通了。

现在总结下问题现象是跨网络通信偶尔失败。

由于我的服务下面的机器非常多,我给出一种猜测:有可能部分机器网络不通。
于是我建议客户端写死服务端IP,看能否重现问题。

好久之后,客户端测试确认固定的一台机器,问题依旧存在,偶尔失败。

于是可以确认网络确实是通的,是其他问题。

四、抓包

固定的机器可以重现问题,那一般抓包就能解决了。

抓包后,没发现包非常多,原来这个问题发生的概率是非常低的。

今天我还有很多其他事情做,于是我又给出一个建议:先请求自己的服务,如果也能重现,那就不需要我参与这个事情了。
他们回答自己的服务也可以重现这个问题,我便潜水了。

后来他们又说自己的服务又不能重现了。
他们去我的服务器上抓包,确认发给服务端SYN包后服务端没回包。

看到服务端没回TCP三次握手的第一个 SYN 包,我大概知道什么问题了。

TCP的三次握手属于操作系统级别的通信,与服务端无关。
既然遇到这种事情,那肯定是系统配置问题了。

五、NAT遇到TW快速回收

什么时候服务端会不对 SYN 回包呢?
很简单,SYN 包异常或者受到 SYN 攻击,syns queue满了。

但是非云上的请求都没有问题,可以排除 SYN 攻击,那就是 SYN 包异常了。

什么时候 SYN包会被认为是异常而不会回包呢?
只有一种可能,被认为是无效的 SYN 包会被丢弃而不会重传。

而什么时候正常的包会被认为无效呢?
打开 TIME_WAIT 快速回收后,NAT 后的包可能会因为时间戳乱序而丢掉一些包。

而我们内网的大部分机器都打开了快速回收。
到这时候,原因差不多确认了。

接下来就是验证猜想了。
关闭前测试一下失败率,关闭后再测试一下失败率,发现关闭后几乎没失败了。

到目前为止,算是问题解决了。

这一小节里的知识其实你了解也没关系,直接去 google 搜索 没回 syn 包,马上就可以找到所有可能的。
上面我根据自己的理解写了两种原因,有没有其他原因你们也可以去了解一下。

六、最后

这次问题前面浪费不少时间,不过看到没回SYN包后一切就很清晰了。

之前我经常和别人谈起 TIME_WAIT,现在终于可以实践一次快速回收的副作用了。

文章介绍的比较简单,给大家一些关键字来搜索吧。

关键字:SYN未回包、TIME_WAIT快速回收

《完》

-EOF-

本文公众号:天空的代码世界
个人微信号:tiankonguse
公众号ID:tiankonguse-code

本文首发于公众号:天空的代码世界,微信号:tiankonguse
如果你想留言,可以在微信里面关注公众号进行留言。

关注公众号,接收最新消息

tiankonguse +
穿越