最近,我们意识到存在一个 TCP 连接问题,该问题主要限于浏览我们网站的 Mac 和 Linux 用户。
从用户的角度来看,这表现为我们与网站的连接时间非常长(>11 秒)。
我们设法追踪了该问题的技术特征,但无法弄清楚其发生的原因或如何解决它。
基本上,发生的情况是客户端的机器正在发送 SYN 数据包以建立 TCP 连接,并且 Web 服务器接收到该数据包,但没有使用 SYN/ACK 数据包进行响应。在客户端发送了许多 SYN 数据包之后,服务器最终使用 SYN/ACK 数据包进行响应,并且连接的其余部分一切正常。
当然,问题的关键在于:它是间歇性的,并不是一直发生的(尽管它确实会在 10-30% 的时间内发生)
我们使用 Fedora 12 Linux 作为操作系统,并使用 Nginx 作为 Web 服务器。
wireshark分析截图
更新:
关闭客户端上的窗口缩放功能可阻止该问题的发生。现在我只需要一个服务器端解决方案(我们不能让所有客户端都这样做):)
最后更新:
解决方案是关闭两者TCP 窗口缩放 和 TCP 时间戳在我们可供公众访问的服务器上。
答案1
答案2
就我而言,以下命令已修复 Linux 服务器缺少 SYN/ACK 回复的问题:
sysctl -w net.ipv4.tcp_tw_recycle=0
我认为这比禁用 TCP 时间戳更合适,因为 TCP 时间戳可用于高性能(PAWS、窗口缩放等)。
文档中tcp_tw_recycle
明确指出不建议启用它,因为许多 NAT 路由器保留时间戳,这可能会导致 PAWS(针对包装序列的保护)激活,因为来自同一源 IP 地址的时间戳可能会变得不一致。
tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4) Enable fast recycling of TIME_WAIT sockets. Enabling this option is not recommended for devices communicating with the general Internet or using NAT (Network Address Translation). Since some NAT gateways pass through IP timestamp values, one IP can appear to have non-increasing timestamps. See RFC 1323 (PAWS), RFC 6191.
答案3
只是想知道,为什么对于 SYN 数据包(帧#539;已被接受的数据包),“信息”列中缺少 WS 和 TSV 字段?
WS 是TCP 窗口缩放TSV 是时间戳值。它们都在 tcp.options 字段下找到,如果它们存在,Wireshark 仍应显示它们。也许客户端 TCP/IP 堆栈在第 8 次尝试时重新发送了不同的 SYN 数据包,这就是它突然被确认的原因?
您能为我们提供帧 539 的内部值吗?SYN/ACK 是否始终针对未启用 WS 的 SYN 数据包发送?
答案4
SYN/ACK 丢失可能是由于防火墙上的 SYNFLOOD 保护限制过低造成的。这取决于用户与服务器建立的连接数。使用 spdy 可以减少连接数,并且在关闭 spdynet.ipv4.tcp_timestamps
不起作用的情况下可能会有所帮助。