问题:为什么你的 SYN 包被丢了——求答案
江湖有个传说:一旦设置了 net.ipv4.tcp_tw_recycle 在 NAT 场景下(多个客户端经过一个 LVS 访问一个服务端,NAT 后服务端看到的客户端是同一个 IP) 就会发生丢包
也可以看看这节:https://xiaolincoding.com/network/3_tcp/syn_drop.html#%E5%9D%91%E7%88%B9%E7%9A%84-tcp-tw-recycle
我们来重现和分析一下这个问题,这应该会是个连续剧,我会根据大家实验情况来推进后面的内容
客户端
我们默认 99 的 ECS 就行,默认配置。
1 | yum install tcptraceroute //装一下这个工具,可以对端口进行探测 |
想要持续对端口探测,类似 ping 一样,就装一下下面的 shell 脚本(tcpping , tcpping 里面会调用 tcptraceroute ):
介绍:http://www.vdberg.org/~richard/tcpping.html
脚本我放仓库里了:https://github.com/plantegg/programmer_case/commit/7c59a7d3666db2fe5af9ba598104cd88cad52497
探测端口通不通:
1 | tcpping -d 1.2.3.4 22 |
通的话会收到:
1 | seq 0: tcp response from e237 <syn,ack> 0.088 ms |
端口不存在肯定不通,且会被 RST
1 | seq 3: tcp response from e237 <rst,ack> 0.076 ms |
端口在但是偶尔不通,是今天的主角:
1 | Thu Aug 8 16:48:44 CST 2024 |
服务端
建议找一个 3.10 内核的机器,4.13 开始已经没有 tcp_tw_recycle 这个参数了
1 | #sysctl -a |egrep "recycle|timestamp" |
实验步骤
- 服务端随便起一个 http 服务端口,比如 1234
- 在客户端上执行 tcpping -d 服务端 ip 1234 //这一步可以看到 100% 是通的
- 在客户端执行下 curl 服务端 ip:1234 //可以很快看到 tcpping 开始报偶尔通/偶尔不通
重现效果,如下图,本来一次都没有 timeout,但我 curl 一下立即就 timeout 了
请分析,为什么 curl 一下 tcpping 就不通了?