Skip to main content

请求超时

tcpdump、wireshark

排查高频超时问题-样本下载服务

某段时间,样本下载服务,较高频率的出现i/o timeout,导致样本下载失败率上升。而诡异的点在于,对方网关层nginx没有输出任何错误日志。

经过初步排查,客户端和服务端网络基本是没有问题的,因为只是部分样本下载才会发生超时,大部分样本仍旧是可以正常下载的。

为了进一步排查问题,我们使用了tcpdump和wireshark进行抓包分析。

tcpdump抓包
tcpdump -i any tcp and host afdfs.antiy and port 80 -w /workplace/sample.tcp.pcap
模拟样本下载
curl -O http://afdfs.antiy/sampleHash

通过抓包我们发现,部分请求有概率性会触发五次TCP RetransmissionSYN报文重传,最终导致超时。

2   0.000009    172.17.0.2  192.168.13.192  TCP 76  [TCP Retransmission] 40838 → 80 [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM TSval=2851106709 TSecr=0 WS=128

通过咨询运维近期做了什么线上tcp级别的改造时,对方回复为了调试tidb,需要开启net.ipv4.tcp_timestamps参数。

然后让对方提供了

  • net.ipv4.tcp_timestamps:时间戳选项,一个是便于精确计算 RTT ,另一个是能防止序列号回绕(PAWS)
  • net.ipv4.tcp_tw_reuse:在调用 connect() 函数时,如果内核选择到的端口,已经被相同四元组的连接占用的时候,就会判断该连接是否处于 TIME_WAIT 状态,如果该连接处于 TIME_WAIT 状态并且 TIME_WAIT 状态持续的时间超过了 1 秒,那么就会重用这个连接,然后就可以正常使用该端口了。所以该选项只适用于连接发起方。
  • net.ipv4.tcp_tw_recycle:如果开启该选项的话,允许处于 TIME_WAIT 状态的连接被快速回收,该参数在 NAT 的网络下是不安全的!

最尴尬的问题是,客户端部署在K8S集群中,而样本存储服务部署在单独的物理机上,因此这是一个天然的NAT场景。

当我们开启了tcp_tw_recycle时,服务端会校验IP和Timestamp,对于同IP请求,落后于已处理Timestamp的报文都会直接丢弃。 超时重传默认是5次,意味着在高并发场景下,我5次SYN报文全被丢弃了。

修复方案:修改为110