[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