ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

TCP与IP协议的区别与协作:从分层原理到网络排障实战

TCP与IP协议的区别与协作:从分层原理到网络排障实战 搞网络排查这些年我见过最多的一种情况是项目一卡顿第一反应先怀疑“TCP连接断了”结果抓包一看地址都没配通是IP层的锅还有一种反过来的盯着IP地址冲突折腾半天其实服务端口根本没起来。这个现象背后其实是个老问题——很多人对TCP和IP这两个协议的理解始终停留在“概念上认识、实战上混乱”。TCP/IP协议族是互联网的基石但TCP和IP在里面各自扮演什么角色、哪儿相同哪儿不同、出问题时怎么区分才是真正决定你能不能快速定位问题的能力。这篇我就结合这些年的实操经验把TCP和IP协议的关系掰开揉碎讲清楚目标是让做开发、做运维、甚至刚入门的朋友读完都能在网络上“找对方向”。1. 为什么从来只有TCP/IP没有IP/TCP1.1 TCP/IP不是两个协议是一整套协议族先纠正一个最常见的误解TCP/IP不是“TCP”和“IP”两个协议的合称而是一整套协议族的名字标准说法叫Internet Protocol Suite。TCP和IP只是这套体系里最有名的两个核心协议就像一家公司的两位明星高管——公司叫“TCP/IP有限公司”但公司里还坐着UDP、ICMP、ARP、HTTP、DNS等一大堆员工。这套协议族从1970年代美国国防部高级研究计划局的ARPANET项目里长出来当时Vint Cerf和Bob Kahn发表了那篇著名的《A Protocol for Packet Network Intercommunication》最早设计出来的传输层协议叫NCP后来拆成TCP和IP两个层次整个协议集合被统称为“TCP/IP”这个名字一直沿用到现在。所以你会发现一个有趣的事实为什么常说TCP/IP而不是IP/TCP因为TCP的“资历”更老、更出名网上讨论网络优化时谈的也是“TCP调优”居多IP这个底座反而常常被一笔带过。理解TCP/IP是一整套协议族很重要因为它决定了我们讨论“异同”时的坐标系TCP和IP不是孤零零的两个东西而是同一套网络体系里上下相邻的两层。要比较它们得先看清它们各自站在哪一层、管什么事。1.2 分层不是摆设每一层都有各自的盘算网络通信为什么非要分层我用一个很直白的理由来解释分层是为了让技术可以独立演进。底层铜缆换成光纤上层应用不需要跟着改上层加一个新的应用协议底层设备也不用动。这就是“封装”和“解耦”的价值。TCP/IP通常被画成四层模型经常会拿来和OSI七层模型对照链路层对应OSI的数据链路层物理层处理网卡、以太网帧、Wi-Fi等MAC地址在这里。网络层对应OSI的网络层核心就是IP协议负责寻址和路由。传输层对应OSI的传输层核心是TCP和UDP负责端到端的通信管理。应用层对应OSI的高三层合并HTTP、FTP、DNS、SSH等都在这里。熟悉OSI的朋友会看到TCP/IP的四层模型是OSI七层的精简版。实际工程里几乎没人严格背着七层跑大家口里说的“网络分层”默认就是TCP/IP四层模型。用寄快递来类比最贴切应用层是你写的信内容随便你想表达什么TCP是快递公司的客服负责打电话确认对方“收到了没”“缺不缺件”缺了安排补寄IP是物流中心的地址分拣系统负责看门牌号IP地址、规划线路、把包裹一站站转运链路层则是具体的那辆货车和你家门口的路。有了这个坐标系再来看TCP和IP各自管什么就很清楚了。2. IP负责找人TCP负责说清事情2.1 IP无连接、尽力而为的“寻路系统”IP位于网络层它的活儿就两件寻址和转发。给每一台接入网络的主机分配一个逻辑地址IPv4的32位地址或IPv6的128位地址然后根据目的IP地址决定数据包下一个该丢给谁一站一站传到目的地。IP层的一个关键设计是“无连接”。什么意思就是IP协议本身不维护任何“会话状态”。每个IP数据包都是独立的个体发出去就发出去了路由器只需要看包头的目的地址查一下路由表决定下一跳根本不需要记住这个包属于谁的连接。这带来一个巨大的工程优势路由器不用保存海量的会话状态硬件可以高速转发这让互联网能撑起今天这个体量。另一个关键设计是“尽力而为”。IP不保证数据包一定能到达也不保证到达顺序和发送顺序一致更不保证不重复、不丢包。路由拥塞了路由器会直接丢弃数据包路径变化了同一个会话的包可能走不同路线到达时顺序颠倒。这些“不靠谱”在IP层看来都是正常的。IP层做的最多就是包坏了头部校验不过就丢弃然后用ICMP回一个差错消息告诉源主机“我丢了你的包”仅此而已。IP超然于“连接”之外它只认“IP地址”这一个门牌号。两台机器之间能不能通信IP层只关心地址对不对、路由通不通至于对方主机上的哪个程序在收IP不知道也不想知道。2.2 TCP有连接、有状态的“端到端管家”TCP位于传输层管的是两台主机上“具体进程与进程之间”的通信。它引入的最重要的概念是端口号——IP地址定位到某台主机端口号定位到主机上的某个服务流水号、进程入口。所以一条TCP连接用四元组唯一标识源IP、源端口、目的IP、目的端口。TCP和IP最大的区别就在“状态”二字。TCP是面向连接的通信双方要先建立一个“逻辑连接”然后才能传数据。注意这个连接是“虚”的——它不像电话线路那样物理占有一条通道本质上只是通信两端各自记录一组状态参数序列号、确认号、窗口等彼此约定好按这套参数收发。所谓“三次握手”就是双方把这套初始状态敲定下来的过程。建立连接之后TCP用一整套机制保证“可靠交付”编号每个字节都有序列号接收方按序列号拼装数据。确认收到数据就回ACK确认没收到就重传。重传超时没收到ACK就重发收到三个重复ACK可以快速重传。校验TCP头和数据有校验和发现损坏直接丢弃并要求重传。流量控制通过窗口字段告诉对端“我的缓冲区还能收多少”避免撑爆接收方。拥塞控制慢启动、拥塞避免、快重传、快恢复探测网络当前能承受多少数据避免把网络堵死。这些机制是IP层完全不具备的。所以你可以这么理解IP把一个包裹扔进一个大物流网说“能送到最好但我无法保证”TCP则是那个拿着电话守在电话旁的客服“我用序列号记着发了多少个箱子每收到一个回执就核对一下缺了马上让寄件方补发最后全部到齐了才告诉你齐了收货吧。”2.3 一张表看清异同很多朋友喜欢逼我总结一张对比表那我直接给对比维度IP协议TCP协议所属层次网络层传输层核心目标寻址与路由把数据包送到目的主机端到端可靠传输把数据完整交给目标进程寻址方式IP地址四元组源IP源端口目的IP目的端口是否面向连接无连接面向连接虚连接是否维护状态无状态有状态序列号、确认号、窗口状态等可靠性保证尽力而为不保证送达可靠交付重传、排序、确认头部最小开销IPv4头部20字节TCP头部20字节发送单位IP数据包TCP段典型故障表现网络不可达、路由黑洞、地址冲突握手超时、连接被重置、端口不通代表性机制路由选择、分片、ICMP差错报告三次握手、滑动窗口、拥塞控制、四次挥手被说成“异同”我们当然不能只讲“异”。TCP和IP至少有四个地方是相通的同属一个协议族都定义在RFC标准里头部都讲究字节对齐。都运行在“网络不可靠”这个大前提下只是应对策略不同——IP选择接受不可靠TCP选择在不可靠之上构建可靠。都基于“包交换”不是电路交换数据和路径不绑定。实际通信中必须配合使用IP负责把包送到主机TCP负责把数据流完整交给应用缺一不可。3. 一次网页访问看清TCP和IP各干了什么3.1 从输入URL到TCP三次握手理论讲完了用一个最日常的场景串起来你在浏览器输入一个网址回车网页打开。这中间TCP和IP是如何各司其职的第一步是DNS解析。浏览器要先知道网址对应的IP地址——这是IP层的首次出场你得先拿到对方的“门牌号”。DNS请求本身用的是UDP特殊情况会用TCP但无论如何目标主机的IP地址是整个通信的前提。拿到IP后浏览器开始发起TCP连接。这就是著名的三次握手客户端发送SYN报文携带一个初始序列号x这个数是随机生成的用于防止伪造连接。服务端收到SYN后回复SYNACK报文携带自己的初始序列号y同时确认号ackx1表示“我收到你的编号了期待你下一个字节的编号是x1”。客户端再回一个ACK报文确认号acky1握手完成连接进入ESTABLISHED状态。为什么必须是三次而不是两次关键原因是要防止历史失效SYN报文造成“死锁”。想象一个场景客户端发出SYN被网络卡了很久才到达服务端此时客户端已经放弃。如果只要两次握手服务端收到这个迟到的SYN后会以为自己建立了连接一直傻等数据浪费资源。三次握手中客户端收到服务端SYNACK后会根据自己的状态判断如果自己确实在等待连接就回ACK如果这压根是历史残留连接就回RST拒绝。服务端只有收到ACK才能确认双方状态一致。三次握手不是没有代价它至少消耗一个RTT往返时间。所以HTTP协议设计出Keep-Alive长连接复用同一个TCP连接处理多个请求TLS 1.3更是引入了0-RTT恢复机制这些都是为了省掉握手开销。3.2 数据封装TCP分段与IP分片是两回事握手完成浏览器把HTTP请求丢给TCP。这里TCP做的第一件事是“分段”也就是按MSS把应用数据切成一块块合适大小的TCP段。MSS怎么算以太网MTU是1500字节IP头20字节、TCP头20字节所以MSS1460字节。超过1460字节的数据就要分成多个TCP段每个段加上TCP头后塞进一个IP包。这里有一个特别容易混淆的点TCP的分段和IP的分片是完全两回事。TCP分段发生在源主机是端到端的主动行为源端知道对方MSS主动把数据切成适合的大小。IP分片发生在路径上的路由器当中间某个链路的MTU比源端认为的更小比如PPPoE拨号网络MTU只有1492字节IP包太大塞不下路由器就会把IP包切成碎片。IP分片是“被动”的、中间设备的行为而且碎片一旦丢失会导致整个原始包重传效率很低所以现代主机一般都会设置DF位不分片标志通过PMTUD路径MTU发现机制提前探测整条路径的最小MTU。你可以这样理解TCP分段是“发货前按箱子规格打包”IP分片是“运输途中遇到窄门被迫把箱子锯开”。前者可控后者不可控——这就是TCP/IP设计中能不做的事尽量在端到端做、中间设备尽量少干活的思想。接着看封装顺序HTTP数据交给TCP加上TCP头变成TCP段TCP段交给IP加上IP头变成IP包IP包交给链路层加上以太网帧头和帧尾变成帧最后变成电信号发出去。每一层只关心自己头部里面那点事儿这就是分层思想的实际落地。3.3 一路转发、四次挥手与连接消亡IP包在网络上奔波时沿途的每个路由器都只干一件事读取IP包头里的目的地址对照路由表决定下一跳给谁。路由器根本不会去看TCP头的端口号也不知道这个包属于哪条HTTP请求——对IP层来说它的任务就是“把这个包丢给下一站”。等数据到了目标主机链路层帧被剥掉IP包被交给IP模块IP模块发现“协议号是6TCP”就把载荷交给TCP模块TCP模块校验完整性、按序列号拼装交给应用层的HTTP服务。整个过程里IP只做了“送达”TCP做了“管到底”。数据传完后还要断开连接这就是传说中的四次挥手主动关闭方比如客户端发送FIN表示“我的数据发完了”。被动关闭方回ACK表示“我知道了但我可能还有数据要发”。被动关闭方把剩余数据发完后也发FIN表示“我这边也发完了”。主动关闭方回ACK连接关闭。为什么是四次而不是三次因为TCP连接是全双工的两个方向的通道是独立的关闭也要独立关。步骤2和3不能合并是因为被动方收到FIN时可能还没发完数据必须等自己发完才能FIN。之所以很多人看到三次就结束是因为被动方发完数据后它的ACK和FIN经常被合并成同一个报文发送抓包时就会看到三条消息。挥手结束前还有最后一个值得记住的东西TIME_WAIT状态。主动关闭方发送最后一个ACK后不会立刻关闭而是进入TIME_WAIT等待2MSL报文最大生存时间两倍通常60秒左右。这是为了让可能迟到的数据包在网络上自然消亡避免影响新连接。生产中你拿netstat看到大量TIME_WAIT不要慌这是TCP在“打扫战场”属于正常生理现象。一次网页访问TCP和IP就是这样你方唱罢我登场IP负责找到人、把包裹一站站运过去TCP负责管好“说了没、收到没、完整没、速率别把人堵死”这些精细活。4. 别用谁强谁弱来看它们4.1 可靠是TCP的优势也是代价我做性能排查时经常碰到一句话“TCP比IP高级可靠嘛。”这种说法其实站不住脚。可靠是有代价的而且代价不小。TCP的可靠靠什么换来的首先是头部开销TCP头最小20字节加IP头20字节总开销40字节起步在语音这类小包场景里占比相当可观。其次是确认机制每个包都要ACK高频往返会吃掉不少吞吐。最让人头疼的是队头阻塞TCP要保序如果一个包的ACK迟迟不来后面即便已经收到的包也不能交付给应用层因为顺序乱了应用没法拼。一个丢包就能让整条连接卡顿。TCP的拥塞控制同样不是免费的。经典的慢启动算法要求连接建立后从很小的拥塞窗口开始逐步加倍探测带宽这在长肥管道高带宽高延迟链路上要花很多个RTT才能把带宽“跑满”。我们判断一条TCP连接性能好不好经常看四个指标重传率、乱序率、RTT和拥塞窗口。这就暴露了TCP的“本性”它把可靠性管得越严网络利用率可能反而越低因为它在小心翼翼地试探这个网络到底能承受多少。所以我处理高并发系统时通常花大量时间调TCP参数增大初始拥塞窗口、开启选择性确认SACK、调整接收窗口自动调优、配置合适的keepalive时间。调这些本质上就是在“用配置换可靠性和速度的平衡”。这就是为什么做网络优化的人不会简单说“TCP就是好”而是会说“TCP是一个可调性极强的协议”。4.2 IP的尽力而为反而成就了扩展性再说IP。很多人觉得“尽力而为”是IP不够强但实际上这恰恰是它能撑起全球互联网的原因。IP层不维护状态意味着转发设备内部只有一张路由表没有几十万条并发会话记录不用跟踪“这个包属于哪个用户、下一步应该发送什么”。这种“傻白甜”的设计让路由器可以做到几十上百Gbps的线速转发也是运营商敢把骨干设备铺到全球的原因。你看底层设备越忙越需要简单的行为模型。因为IP“不管连接”各种扩展协议才有生存空间ICMP在网络层探测路径和报告差错IGMP支持组播NAT在边缘设备上做地址转换ACL、QoS都在IP层实施策略。这些功能的共同点就是只摸IP包头不需要关心上层是不是TCP、是不是HTTP。你可以把IP层理解成一个极宽松的平台——只要按它的格式封装好谁都能在上面跑这也让它成为整个互联网事实上的“通用底座”。换个角度看如果IP也像TCP一样维护海量状态那路由器早就被压垮了。4.3 UDP的存在提醒我们不是所有传输都需要TCP聊到TCP的“可靠代价”和IP的“扩展红利”有个非常好的参照系是UDP。UDP也在传输层和TCP共用IP这个底座但它比TCP激进得多没有握手没有确认没有重传没有状态头部只有8字节。UDP靠IP层提供的“尽力而为”直接干活把可靠性完全交给应用自己决定。什么时候你会主动抛弃TCP、投奔UDP直播场景一帧画面迟到比丢更糟糕重传只会让流卡得更久所以宁可丢掉也不要等语音通话实时性大于准确性DNS查询请求响应一次完事根本不需要连接还有HTTP/3直接跑在UDP之上把可靠传输搬到了应用层和QUIC从而绕开了TCP的队头阻塞——因为在多路复用场景里TCP对每个独立资源流的队头阻塞是没法接受的。这才是看待TCP和IP真正该有的姿态它们之间没有优劣之分只有舍取和分工。IP用简单换来了互联网的规模TCP用复杂换来了应用的安心。UDP则证明“可靠”不是传输层的必然义务而是一种可选择的“服务等级”。5. 排障实战——先分锅再动手5.1 通用定位法连通性决定先查哪层我把这些年排查网络问题的经验浓缩成一个心法TCP/IP是分层的排查也必须分层别一上来就钻到细节里。最简单的定位口诀是先ping后端口再业务。这个顺序决定了你从哪一层开始查检测手段检测目标通过说明什么不通过说明什么pingIP层连通性网络层基本通不排除丢包IP层问题或被防火墙策略屏蔽ICMPtracert/tracerouteIP层路径看到每跳延迟和丢包率中间某跳路由黑洞或策略丢弃telnet/nc 测试端口TCP层连通性TCP握手能成功服务未监听、防火墙丢SYN、连接队列满ss/netstat 查看状态TCP层本地状态看到LISTEN、ESTABLISHED、TIME_WAIT等端口没监听、队列溢出、握手失败业务请求测试应用层业务逻辑正常TSL/HTTP/应用自身问题有个细节要特别提醒ping不通不等于IP层一定断了。很多系统为了安全会直接丢弃ICMP报文这是主机防火墙或路由策略干的活属于ICMP被禁不代表TCP数据也过不去。判定IP层的时候要学会用多种手段交叉验证能ping通附近的网关、能访问同网段服务器、traceroute能看到第一跳这些都可以佐证链路状态。5.2 IP层问题的几个常见案例IP层故障通常有非常明确的症状要么完全不可达要么时通时断要么地址根本分不到。第一种是IP地址冲突。典型场景是你往局域网里接了一个设备或者虚拟机没配置好然后整片网络开始出现“某些机器通、某些机器不通”的灵异现象。排查手法是抓包看ARP正常的ARP应答是MAC和IP的映射如果收到多个不同的MAC回应同一个IP的ARP请求那就是地址冲突了。还有一种简单的物理判断法拔掉可疑设备的网线网络立刻恢复。新建局域网规划时最好把DHCP地址池和静态IP段分开避免冲突。第二种是DHCP获取不到地址。手机开热点后“IP配置失败”、虚拟机反复拿不到IP多半是DHCP服务器故障、租约池耗尽、或者跨网段中继配置有误。注意排查时先看网卡有没有拿到169.254开头的APIPA地址那是Windows拿不到地址时的“自嘲地址”看到了直接锁定DHCP问题。第三种是路由黑洞。你ping目标不通但ping同网段网关是通的traceroute一下发现某个中间跳有来无回。可能原因是对端防火墙丢弃、路由宣告错误、或者中间设备的负载均衡策略异常。这类问题的特点是“看上去通了一部分实际上是半死状态”必须用traceroute逐跳定位。5.3 TCP层问题的几个常见案例IP层通了但TCP连不上那就是TCP的锅。这类问题最典型的症状是“ping通但业务连不上”。案例一Docker发布端口失败。报错类似“ports are not available: exposing port tcp 0.0.0.0:xxx”。这是典型的TCP端口已被占用。处理很简单用ss -lntp或者netstat -ano找到那个进程确认是不是该占、要不要杀掉或者换端口。我遇到过不少同事在容器编排里写了固定的host port两台机器同一个端口都绑docker起容器时必然有一台失败。好的习惯是让宿主机端口随机映射或者用服务网格统一管理端口规划。案例二Harbor推送镜像时报“dial tcp 192.168.209.133:443: connect: connection refused”。这个报错信息的核心是“dial tcp”失败——本机发起的TCP连接根本没能建立。先不要急着折腾registry配置按顺序查目标IP能不能ping通IP层、443端口通不通TCP层、Harbor容器有没有监听服务层、是不是有防火墙把443拦了策略层。我实际处理过类似问题最后发现是目标主机上Harbor服务因为磁盘满了起不来ping通、端口却不监听属于纯TCP层“无人在线”。案例三SYN收不到回复连接一直挂着。抓包看客户端重传SYN服务端不回应。原因可能是服务端的连接队列满了。Linux下有两个队列半连接队列syn queue和全连接队列accept queue。半连接队列溢出时内核直接丢弃SYN包表现为“客户端SYN发出石沉大海”全连接队列溢出时TCP虽然完成握手但仍拒绝应用accept表现为“握手能看到但业务无法建立”。排查命令很简单ss -lnt查看Send-Q表示队列最大长度和Recv-Q当前积压数量netstat -s看“SYNs to LISTEN sockets dropped”计数。调优方向一般是调大小、调net.ipv4.tcp_syncookies以及加快应用accept。案例四Windows下TCP时间戳调试。很多人搜过netsh int tcp set global timestampsenabled这条命令它用于开启TCP时间戳选项。TCP时间戳在高带宽高延迟链路上能更精确地计算往返时间有助于RTT估算也能配合防序列号回绕。Windows默认策略是部分场景关闭改它的前提是两端都开启才有效。我一般只在做TCP性能对比实验时才动它生产环境不会盲目全局开启因为时间戳选项每个包多占12字节而且对绝大多数内网场景没感知收益。5.4 学习环境里怎么练排查理论说再多不如拿真包练一次。我特别推荐用GNS3自己搭一个模拟网络两个路由器分别连接两台主机然后在主机上ping对方同时抓包你会亲眼看到完整的过程——首先是ARP请求找对端MAC接着ICMP Echo Request被封装成IP包走路由器转发路由器逐跳修改TTL和校验和最后送到目的地。这个实验几乎把IP层的工作机制完整演了一遍。如果条件有限用一个虚拟机也能练修改虚拟机的IP地址后如果出现“找不到对方设备”很可能是ARP缓存没刷新。在Windows上执行arp -d清空缓存在Linux上执行ip neigh flush all网络立刻恢复。这类小实验做上几次你对IP和TCP各自负责什么的直觉就会完全建立起来。6. 从抓包里直观读懂TCP和IP6.1 抓包前需要准备什么纸上谈兵够多了最后一节直接上干货——怎样用Wireshark或tcpdump“看见”TCP和IP各自干活的样子。学习阶段我在GNS3里抓包生产环境则用tcpdump在服务器上抓。几个最常用的过滤条件先记下来# 按主机过滤只抓和某台机器交互的流量 tcpdump -i eth0 host 192.168.1.10 # 按端口过滤只看TCP 80端口 tcpdump -i eth0 tcp port 80 # 同时过滤方向和协议抓某个IP发出的TCP SYN包 tcpdump -i eth0 src host 192.168.1.10 and tcp[tcpflags] tcp-syn ! 0在Windows上可以用Wireshark直接基于图形界面抓包Win10以上还支持用netsh trace抓回环流量。抓包尽量在自己控制的设备上做不要在别人的网络里随便抓——这既是合规问题也是职业操守。6.2 报文解读IP头与TCP头逐个字段过抓到一个TCP SYN包展开它的IP层和TCP层你会看到下面这样的结构IP Header: Version: 4 Header Length: 20 bytes Total Length: 40 bytes Identification: 0x1234 Flags: 0x02 (Dont Fragment) Time to Live: 64 Protocol: 6 (TCP) Header Checksum: 0xabcd Source Address: 192.168.1.10 Destination Address: 192.168.1.20 TCP Header: Source Port: 54321 Destination Port: 443 Sequence Number: 2415780182 Acknowledgment Number: 0 Header Length: 20 bytes Flags: 0x002 (SYN) Window Size Value: 64240 Checksum: 0xef12看IP头的关键字段Protocol6说明上层是TCPTTL64说明这个包从源主机发出后没被转发过几次每经过一个路由器TTL减1Total Length40正好是IP头20字节加TCP头20字节说明这是一个没有载荷的纯握手包。看TCP头的关键字段Source Port是客户端临时端口Destination Port是HTTPS的443Sequence Number是客户端初始序列号此时还没收到服务端任何数据所以Acknowledgment Number是0Flags显示SYN说明这是三次握手的第一步。有个深度细节值得了解TCP校验和的计算不只是基于TCP头和负载它还有一个“伪首部”包含源IP、目的IP、协议号和TCP长度。有线抓包工具算TCP校验和时必须知道IP层的地址信息。这从侧面说明TCP和IP虽然是两层但校验机制是联动的——TCP的可靠性建立在IP地址正确的基础上。6.3 TCP重传和乱序的判读思路抓包不只为了“看懂”更多是为了判断问题性质。我排障时最关注下面三种现象第一是TCP Retransmission超时重传。原始包发出去等待了很久没等到ACK于是又发一遍。出现大量重传说明网络丢包率很高优先查链路质量和拥塞。需要说明的是抓包软件显示的“Retransmission”是它根据序列号自己推断的实际网络里重传可能有很多层原因。第二是Dup ACK重复确认。接收方收到乱序包时会重复发送上一次正确接收到的序号让发送方知道“我缺哪个片段”。连续收到3个Dup ACK就触发快速重传不用等超时。如果抓包看到大量Dup ACK但重传不多说明网络乱序严重而不只是简单丢包。第三是Out-of-Order乱序到达。序列号出现跳跃TCP层的拼装机制在起作用。这种情况在路径变化频繁的网络里很常见也不一定代表“故障”但如果伴随业务延迟明显你就得看看是不是有多径负载不均的问题。我处理过一台服务器上的偶发延迟问题抓包三个小时才逮到一个丢包确认是物理链路误码率过高。这时TCP的重传机制一直在帮我们“擦屁股”业务虽然没断但延迟上去了。如果只看业务层指标很容易误判成应用性能问题抓包的价值就在于此——它把TCP和IP各自的行为赤裸裸地摆在桌面上让你能精确判断问题的层次归属。最后再分享一个小技巧排障时不要把抓包工具看作“最后的武器”而是从第一步就用起来。最简单的ping包开始抓一路抓到TCP握手、业务数据你会看到IP、TCP、应用三个维度在同一张时间轴上如何交织。看得多了以后别人问你“TCP和IP到底什么关系”你可以淡定地回答一个送件一个管收发一个无连接的做底座一个有状态的做保障——分工不同使命相同。
返回列表