服务端 tcp 丢失SYN/ACK 问题排查

[toc]html

总览

与某公司对接, 发现有 10% 的超时状况. tcp在咱们服务器发现, 有大量 SYN 包重传的状况, 并且只有 SYN包才会重传, 不少包重传失败, 有一些包重传也会成功(注意 Retransmission):nginx

163	2017-12-20 13:27:41.125680	xxx.xxx.xxx.xxx	xxx.xxx.xxx.xxx	TCP	74	[TCP Retransmission] 60671 → 80 [SYN] Seq=0 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=2897178400 TSecr=0 WS=128

最终经过在对方服务端 nginx 和 后台服务器关闭net.ipv4.tcp_tw_recycle功能解决.后端

排查过程

因之前没抓过包, 被同事笑话了一番. 周末买了一本看完<Wireshark网络分析就这么简单()>, 抓住这个机会实战一下.服务器

让对方分别在 nginx 和 后端服务器上抓了包. 显示, nginx 上请求包和咱们机器上抓包现象相同. 可是 nginx 到 后端服务器的包都正常. 也就是说, nginx 没有及时处理TCP链接请求.网络

排查了一下nginx机器负载, 以及基本配置都没有问题. 既然只有 SYN 类型包重传, 现象很明显, 就Google了一下. 找到这个帖子: 为何服务端不回复 SYN/ACK. 问题和咱们的如出一辙. 可是题主给出的解决方法存疑. 并且没有给出为何. 我注意到了帖子中lav的答案, 可能和net.ipv4.tcp_tw_recycle参数相关. 通过查看, 对方果真开启了这个参数.tcp

度娘了一下这个参数, 发现这么一段话(连接:tcp_tw_reuse、tcp_tw_recycle 使用场景及注意事项):code

对于服务端
1. 打开tw_reuse无效

2. 线上环境 tw_recycle 不要打开

   服务器处于NAT 负载后,或者客户端处于NAT后(这是必定的事情,基本公司家庭网络都走NAT);

 公网服务打开就可能形成部分链接失败,内网的话到时能够视状况打开;

   像我所在公司对外服务都放在负载后面,负载会把timestamp 都给清空,好吧,就算你打开也不起做用
4. recycle

    对于服务端,同一个src ip,可能会是NAT后不少机器,这些机器timestamp递增性无可保证,服务器会拒绝非递增请求链接。

结论

因对方开启了net.ipv4.tcp_tw_recycle参数, 这个参数会对同一个请求 IP 按照时间戳增续处理, 凡是小于上次时间戳的连接请求, 都被认为是重传包而丢弃. 咱们后台服务器通过同一个 NAT 访问对方 nginx, 出口IP是一个, 后台服务器访问对方nginx, 请求包里面的 timestamp 可能会有差别. 致使 timestamp 落后的包被对方丢弃.server

解决方法

在对方服务端 nginx 和 后端服务器 把net.ipv4.tcp_tw_recycle参数关闭便可.htm

相关文章
相关标签/搜索