摘要
本文通过一个交易超时案例,探讨 TCP 连接中的重传机制、丢包现象、MTU(最大传输单元)限制导致的传输失败,以及 PMTUD(路径MTU发现)机制作用下如何恢复正常通信。
背景
某个访问互联网的交易系统在处理用户请求时,频繁出现交易超时的问题,技术团队通过抓包分析,试图找出导致交易超时的根本原因。
采集多个样本,团队发现来自不同客户端的两个异常现象具有代表性。尽管它们都涉及到 TCP 连接问题,但在处理重传和丢包时的表现略有不同。接下来,我们将分别详细描述这两个异常现象,并通过对比分析,找出它们的共同点和差异,揭示背后的技术问题。
图-1:访问关系
两种现象
客户端 A 重传失败
在这个样本中,客户端 A 与服务器的初始通信阶段一切正常。TCP 三次握手顺利完成,随后 TLS 握手也成功建立,客户端与服务器之间的加密连接得到确认,数据传输正式开始。
然而,异常很快就发生了。在客户端发送了加密的应用数据后,服务器并未按预期返回 ACK 确认包。经过短暂的等待,客户端触发了 TCP 重传机制,开始重发之前的报文。
图-2:客户端 A 的异常通信过程
在 TCP 协议中,重传机制是应对网络中的数据包丢失或延迟的一种关键手段。通常情况下,当客户端发送的报文未能在预期时间内获得服务器的确认时,它会启动重传。重传初期,客户端会以较短的时间间隔(约 1 秒左右)进行重发,但随着多次重传失败,时间间隔逐渐拉长。客户端一再经历了数次重传后,最终的重传时间间隔达到了 5 秒。
与此同时,服务器也在这一过程中发送了多个重复的 ACK 包。重复 ACK 通常是 TCP 协议在检测到数据包丢失或乱序时发送的一种反馈信号。这些重复的 ACK 表明,服务器确认已经接收到之前的部分数据,但未能接收到客户端正在重传的那部分数据(Seq=402)。
尽管客户端持续尝试重传,网络的传输状况并未得到改善。客户端和服务器之间的通信陷入僵局,最终导致 TCP 连接超时,交易未能完成。这个异常现象突出了网络路径中存在的丢包问题,并表明 TCP 的重传机制在此场景下未能有效恢复连接。
客户端 B 重传成功
相比之下,客户端 B 的交易通信过程表现出略有不同的特征。在最初的 TCP 三次握手和TLS握手阶段,客户端B与服务器之间的连接同样建立顺利。TLS 握手成功后,双方开始交换加密的应用数据。
然而,在不到 0.5 秒的时间内,服务器突然发送了一个 TCP 伪重传包(TCP Spurious Retransmission)。这种伪重传通常表示,服务器错误地认为之前发送的数据包没有被客户端确认,因此重复发送了该数据包。客户端 B 在接收到伪重传包后,立即返回了一个TCP重复确认包(Dup ACK),确认了服务器之前发送的部分数据。从全局来看,触发服务器伪重传的原因是长时间没有收到客户端的报文,超时导致的重传,这说明了客户端发出的报文没有到达服务端。
图-3:客户端 B 的异常通信过程
随后,异常继续发展:客户端 B 触发了 TCP 重传机制,重传了未确认的应用数据。
在这之后的 0.184 秒,服务器返回了一个关键的 ICMP 报文,提示“目标不可达(需要分片)”。这一ICMP 消息表明,网络路径中某个节点的 MTU 小于当前正在传输的数据包大小,因此需要将数据包分片后重新传输。客户端接收到这一信息后,开始调整数据包的大小,以避免继续发送超过路径MTU 限制的数据包。
经过调整和重传,服务器最终发送了新的应用数据,表明数据传输恢复正常,交易成功完成。尽管 TCP 重传现象也在客户端 B 的交易通信过程中出现,但由于 ICMP 报文的及时反馈,客户端得以调整传输策略,避免了更严重的通信中断。
网络路径上有丢包
图-4:故障定位
通过分析上述两个异常现象,首先得出明确结论,捕获点 A 到服务器之间的网络路径上存在丢包。
在 TCP 通信过程中,丢包现象通常通过重传机制来弥补。无论是客户端 A 还是 B,重传机制都被触发,试图恢复通信。
然而,不同的是,客户端 B 在这一过程中收到了来自服务器的 ICMP 报文,提示了网络路径中存在的 MTU 限制问题,而后重传成功。这是如何做到的?
因此,无论是在银行的三方互联、收单系统中,还是在复杂的Kubernetes集群中的应用延迟,这一DNS解析的默认超时时间“5秒”,成为共同的表象。
MTU 和 PMTUD
在深入探讨这两个客户端的不同现象之前,我们有必要了解两个与网络传输相关的关键概念:MTU(最大传输单元)和 PMTUD(路径MTU发现)。
MTU,即最大传输单元,指的是网络中能够传输的最大数据包大小。MTU 设置对于网络传输效率至关重要。较大的 MTU 允许更多的数据在每个数据包中传输,从而减少协议头的开销,提高传输效率。然而,如果数据包的大小超过路径中某个节点的 MTU 限制,数据包就需要进行分片,或者会被丢弃,导致网络性能下降。以太网的标准 MTU 通常为 1500 字节,但在一些特定的网络环境中,MTU 可能会更小。
为了避免数据包过大而被网络设备丢弃,PMTUD(路径MTU发现)机制被引入。PMTUD 通过在数据包的IP头部设置“禁止分片”的标志位,使得当数据包的大小超过网络路径中某个节点的 MTU 限制时,路由器会返回一个 ICMP 报文,通知源主机其需要调整数据包大小。这样,源主机可以根据 ICMP 报文的反馈,逐步减小数据包大小,直到找到适合路径的 MTU 大小,从而避免分片或丢包。PMTUD 的引入使得网络传输能够动态适应不同的网络环境,提高了数据传输的可靠性和效率。
PMTUD 挽救客户端 B
在客户端 B 的异常现象中,PMTUD(路径MTU发现)机制发挥了至关重要的作用。
1.出现MTU问题:由于网络路径中的某个节点 MTU 限制,客户端发送的长字节数据包无法通过该节点,导致网络设备返回了 ICMP Type 3 差错报文,提示“目标不可达,需要分片”。
图-5:ICMP 报文显示下一跳网络设备的 MTU 为 1480
图-6:客户端报文 IP 长度从 1485 调整到 1480
在客户端 B 的 TCP 连接通信过程中,正是通过 PMTUD 的自动调整机制,数据传输得以恢复,最终避免了交易超时的问题。相比之下,客户端 A 没有收到 ICMP 报文,因此未能触发 PMTUD 机制,最终导致了连接中断。
为何客户端 A 没收到 ICMP 报文?
这与网络设备的配置和安全策略有关。
在现代网络设备中,ICMP 报文可能会受到防火墙或路由器的限速或过滤。
设备负载过高:在网络设备负载过高时,设备可能会选择丢弃 ICMP 报文,以保护其 CPU 资源。这种情况通常发生在设备遭受 ICMP 洪泛攻击时。
ICMP 限速和过滤:为了防止 ICMP 洪泛攻击,设备可能会配置 ICMP 报文的限速和过滤功能,直接丢弃不必要的 ICMP 报文。
主流的网络设备厂商如思科、华为、瞻博网络等都在自家的路由器、交换机和防火墙产品上提供了 ICMP 限速功能。这些功能可以有效地防范 ICMP 洪泛攻击,保护设备的 CPU 资源。
当网络设备对 ICMP 报文进行限速或过滤时,某些重要的差错报文可能无法及时传递至客户端。这正是客户端 A 未能收到 MTU 相关 ICMP 报文的原因。由于未能获得服务器的反馈,客户端 A 只有继续以相同的字节长度重传数据包,最终陷入重传失败的困境。
抓包分析建议
以上是单点采集网络报文,诊断分析存在 MTU 限制的过程。如果还要进一步找出 MTU 限制的源头,建议在网络路径的多个关键节点设置抓包点,逐步分析 ICMP 报文的传输情况。通过对比不同节点的抓包数据,可以确定 ICMP 报文在哪个节点被丢弃。具体的抓包分析步骤如下:
扩展抓包点设置:在捕获点 A 到服务器之间的网络路径的其他关键节点,尤其是防火墙、路由器等网络设备处增加抓包点,得以在这些设备前、后都能监控 ICMP 报文的传输情况。
2. 追踪 ICMP 报文丢失点:通过对比各个抓包点的报文,确定 ICMP 报文在哪个节点被丢弃。一旦找到导致 ICMP 报文丢失的设备,可以针对该设备的 ICMP 处理策略进行调整。例如,取消对特定类型 ICMP 报文的限速或过滤,确保 PMTUD 机制中的 ICMP “需要分片”报文能够顺利传递到客户端。
案例分析到这里就结束了,希望通过本文的探讨,读者能够对TCP连接中因为 MTU 限制导致的丢包、重传现象,以及 PMTUD机制有更深入的理解,并能够在实践中灵活应用抓包分析技术,解决类似的问题。
推荐阅读
如果你想更深入了解 PMTUD 实现机制,例如,在 Linux、Windows 操作系统上,不同网络协议诸如 TCP、UDP、Ping 的 PMTUD 行为,推荐阅读:
《Path MTU 概述》http://sunyongfeng.com/201712/networks/path_mtu.html