尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
TCP吞吐量上不去?抓包实测排查带宽跑不满的实战指南
很多人第一次接触网络性能排查都是从带宽明明够为什么速度上不去这个问题开始的。我见过太多同行对着公式一顿推导把吞吐量、窗口、RTT、丢包率算得头头是道结果一到现场就懵——因为真实链路里跑出来的数字和纸面公式差得不是一星半点。这篇东西就是想把抓包实测这条路走通不背公式直接打开抓包工具看数据怎么流、在哪卡、卡在谁身上。核心关键词是TCP吞吐量、抓包实测、带宽跑不满、窗口、RTT、丢包重传。适合谁看刚入行的网络运维、做后端性能调优的开发、以及所有被千兆带宽跑出百兆速度折磨过的人。下面全部是我自己踩过坑之后总结的实操路径工具用Wireshark思路通用换成任何抓包工具都能照搬。1. 先把跑不满这件事拆成可观测的几块1.1 带宽、吞吐量、有效载荷率不是一回事新手最容易犯的错是把链路带宽和应用层吞吐量当成同一个数。一条标称1Gbps的链路指的是物理层/数据链路层每秒能搬运的比特数上限。而你在浏览器里下载文件看到的速度是应用层有效载荷的速率中间隔着TCP/IP各层封装、协议开销、确认机制、重传损耗。这中间的差距就是跑不满的第一层来源。我习惯把这条链路拆成四个可观测的环节抓包时逐个对照观测环节抓包里的体现典型损耗来源物理链路速率无法直接抓靠设备端口计数协商速率、双工不匹配链路层帧速率帧间隔、帧长分布小包过多、前导码与帧间隙开销TCP段速率段大小、段数量协议头开销、SACK、选项字段应用层有效速率载荷字节数/时间重传、乱序、窗口受限、应用处理慢举个具体数字感受一下以太网每个帧有前导码8字节、帧间隙至少12字节的固定开销加上14字节帧头、4字节FCS。一个满载1500字节MTU的帧实际有效载荷是1460字节TCP数据再减去20字节IP头和20字节TCP头应用层能拿到的是1460字节。算下来有效载荷率大约在94%上下。这还没算TCP确认包占用的反向带宽。所以一条1Gbps链路理论上应用层跑到940Mbps左右就已经很漂亮了谁跟你说千兆就该跑满1000M你可以直接把这笔账甩给他。1.2 为什么公式算出来的数和实测总对不上教科书上的吞吐量公式大致是窗口大小除以RTT这个公式本身没错但它描述的是理想稳态下的上限。真实环境里窗口不一定能开满受接收缓冲、拥塞控制、窗口缩放选项影响RTT不是恒定的排队、路由抖动还会插入重传、乱序、零窗口探测这些意外事件。公式给的是天花板实测看到的是地板到天花板之间的某个位置。我的经验是公式用来判断理论上限够不够抓包用来定位实际为什么没到上限。两者是配合关系不是替代关系。你先把理论上限算出来心里有个基准线然后抓包看实际曲线离基准线差多少再顺着抓包里的异常事件往下查。这个顺序很重要反过来先抓包再算容易被海量数据淹没抓了半天不知道自己在找什么。1.3 抓包点选错后面全白干这一条是我踩过最贵的坑。抓包位置决定了你能看到什么、看不到什么。常见三个位置客户端本机、服务端本机、中间链路交换机镜像口或分光。抓在客户端本机能看到应用发出的原始数据、TCP栈的行为但看不到链路中间发生了什么也看不到对端真实收到了什么。抓在服务端本机能看到服务端视角的到达情况适合判断是不是对方发得慢。抓在中间镜像口最接近真相能看到双向流量和真实时序但需要设备支持镜像且镜像口本身可能丢包高负载时尤其明显。我一般至少抓两端客户端和服务端各抓一份用时间戳对齐后对比。单点抓包最大的问题是你只能看到自己这一侧的故事而吞吐量问题是双向的发送方觉得发了接收方可能压根没收到或者收到了但确认回得慢。两端对比才能把责任分清楚。提示镜像口抓包时务必确认镜像会话没有超载丢包否则你抓到的丢包可能是抓包工具自己丢的会把排查方向带偏。判断方法很简单看抓包文件里的帧序号有没有跳变。2. Wireshark里真正该盯的几个字段2.1 用IO Graph先看全局趋势别一上来就翻包打开抓包文件第一件事不是逐包看而是拉出IO Graph看吞吐曲线。菜单路径是统计→I/O图表Y轴选字节/时间粒度选0.1秒或1秒。这一步的目的是建立全局印象吞吐是平稳的、锯齿状的、还是断崖式的。平稳但低于预期通常是窗口或RTT限制锯齿状剧烈波动多半是拥塞控制在做窗口调整或者有周期性重传断崖式下跌然后恢复往往是触发了重传超时或者路由抖动。这三种形态对应的排查方向完全不同先看形态能省掉大量无效翻包。我习惯在IO Graph里同时叠加两条曲线一条是总字节数一条是TCP重传数用过滤器tcp.analysis.retransmission。两条曲线一对比重传尖峰和吞吐下跌是否同步一眼就能看出来。如果同步问题基本锁定在丢包重传如果不同步那吞吐上不去另有原因得往窗口和RTT方向查。2.2 tcp.analysis系列过滤器是排查主力Wireshark的tcp.analysis过滤器族是专门为TCP问题分析设计的用好了能省掉大量手工翻包。我常用的几个tcp.analysis.retransmission重传包最直接的丢包信号。tcp.analysis.fast_retransmission快速重传说明收到了重复ACK通常是单个丢包触发。tcp.analysis.zero_window零窗口通告接收方缓冲满了发送方被迫停发。tcp.analysis.window_update窗口更新配合零窗口看恢复情况。tcp.analysis.duplicate_ack重复ACK快速重传的前置信号。用法上我一般先跑一遍tcp.analysis.flags统计看各类异常事件的数量分布再针对数量最多的那类深入。比如重传占了绝大多数那就重点看重传的分布是集中在某段时间还是均匀散布——集中说明是突发拥塞或链路闪断均匀散布说明链路本身有持续丢包。2.3 窗口字段要看实际生效值而不是通告值TCP头里的窗口字段有两个容易混淆的概念接收方通告的窗口advertised window和发送方实际可用的窗口effective window。通告窗口是接收方说我还能收这么多实际可用窗口还要减去在途未确认的数据量。抓包里直接看到的窗口字段是通告值但真正限制发送的是两者取小。更麻烦的是窗口缩放选项Window Scale。TCP头里的窗口字段只有16位最大65535字节现代网络动辄几百KB的窗口根本装不下所以握手时会协商一个缩放因子实际窗口等于字段值左移缩放位数。Wireshark会自动计算并显示Calculated window size看这个值才准。我见过有人盯着原始窗口字段说窗口才6万多难怪跑不满其实缩放因子是7实际窗口是8MB完全够用。这种误判在排查里非常常见务必看计算后的值。2.4 时间戳精度决定你能不能看清RTTWireshark默认的时间显示精度可能不够看RTT的细微变化。我一般把时间显示格式调成秒的十进制小数精度到微秒级。然后在TCP流的时序图统计→TCP流图形→时间序列里看RTT的波动。RTT的观测有个技巧不要只看单个包的往返要看数据包到对应ACK的配对延迟。Wireshark的tcp.analysis.ack_rtt字段就是干这个的它记录了每个ACK对应的RTT估计值。把这个字段做成IO Graph能看到RTT随时间的完整变化曲线。RTT突然抬升往往对应队列积压是拥塞的前兆RTT持续偏高则说明路径本身有长延迟窗口需求会更大。3. 一次完整的实测从抓包到定位瓶颈3.1 实验环境搭建与抓包准备我搭一个最小可复现的环境来说明。两台机器直连中间过一台交换机一端做服务端跑文件传输另一端做客户端下载链路标称1Gbps。服务端和客户端各开一个Wireshark抓包过滤器都设成只抓这个TCP流用tcp.port 指定端口避免无关流量干扰。抓包前有几个准备动作不能省确认两端网卡协商速率和双工模式一致用系统命令看链路状态别信应该没问题。关闭抓包机器的无关后台流量尤其是自动更新、同步类服务否则抓包里混入噪声。抓包缓冲区调大避免高吞吐时抓包工具自身丢包。Wireshark的捕获选项里把缓冲区设到足够大或者直接用命令行工具抓。记录抓包开始和结束的精确时间方便和业务侧日志对齐。命令行抓包我更推荐资源占用低、不易丢包典型命令# Linux下用tcpdump抓指定端口写入文件后用Wireshark分析 tcpdump -i eth0 -s 0 -w capture.pcap tcp port 5201-s 0表示抓完整包不截断这个参数很关键截断的包会导致Wireshark无法正确解析TCP选项和载荷长度后续统计全乱。3.2 第一轮确认理论上限和实际差距先算理论上限。假设实测RTT是0.5ms同城直连的典型值接收窗口协商到256KB缩放因子配合下那么理论上限约等于256KB除以0.5ms换算成比特每秒大约是4Gbps——远超1Gbps链路说明窗口不是瓶颈链路带宽才是天花板。这种情况下应用层跑到900Mbps以上算正常。如果实测只有300Mbps差距就很大了得往下查。第一轮抓包分析我按这个顺序看IO Graph看吞吐形态是平稳300M还是波动到300M。统计→对话→TCP标签页看这个流的吞吐、包数、重传数汇总。过滤重传包看数量和分布。假设这一轮发现吞吐平稳在300M左右重传极少那基本排除丢包因素问题指向窗口或应用层。接着看窗口在TCP流图形里看窗口大小曲线如果窗口长期停在某个值不再增长说明接收方缓冲或者窗口缩放没生效。3.3 第二轮顺着窗口和RTT往下挖窗口受限的排查有个经典陷阱发送方窗口上不去可能是接收方通告窗口小也可能是拥塞窗口cwnd小还可能是应用层读得慢导致接收缓冲堆积。这三者抓包表现不同接收方通告窗口小TCP头里的窗口字段计算后持续偏小且伴随零窗口或窗口更新频繁。拥塞窗口小抓包里看不到cwnd直接字段但能通过在途数据量推断在途数据量长期远小于通告窗口说明是发送端自己限流。应用层读得慢接收缓冲被占满通告窗口逐渐缩小到零然后周期性窗口更新。我这次实测遇到的是第二种通告窗口很大但在途数据量始终上不去吞吐被压在300M。进一步看发现是拥塞控制处于慢启动后的保守阶段加上路径RTT比预期高实测1.2ms而非0.5ms窗口增长慢。这种情况要么调大初始拥塞窗口要么确认路径RTT为什么偏高是不是中间有队列或者绕路。RTT偏高的排查我在两端抓包对比时间戳客户端发出的包和服务端收到的包时间差就是单向延迟服务端回的ACK和客户端收到的时间差是反向延迟。两者相加是RTT。如果单向延迟明显大于预期往路径方向查如果两端时间差正常但ACK回得慢往服务端处理方向查。3.4 第三轮把重传和乱序单独拎出来看如果前两轮排除了窗口和RTT吞吐还是上不去重传和乱序就是重点嫌疑。重传的排查不能只看数量要看重传的原因和重传的代价。原因上Wireshark会把重传标记成几种超时重传RTO、快速重传、spurious重传其实没丢但被误判。超时重传代价最大因为它会触发拥塞窗口骤降快速重传代价小一些spurious重传说明网络有乱序发送方误以为丢包。代价上一次超时重传可能让cwnd砍半吞吐瞬间掉一半再慢慢爬回来。如果重传是周期性发生的吞吐曲线就会呈现规律的锯齿。我在IO Graph里叠加重传曲线如果锯齿谷底和重传尖峰严格对齐基本可以确认是重传拖累了吞吐。乱序的处理更微妙。轻微乱序本身不直接降吞吐但会触发快速重传和spurious重传间接影响拥塞窗口。抓包里看乱序可以过滤tcp.analysis.out_of_order看乱序发生的频率和幅度。如果乱序频繁且幅度大比如序号跳跃很大要考虑链路是否有负载均衡导致的乱序多路径转发时不同路径延迟不同包到达顺序会乱。4. 那些公式不会告诉你的现场经验4.1 小包多的时候带宽是被帧间隙吃掉的有一次排查一个千兆跑不满的案例吞吐只有400M重传几乎没有窗口也正常怎么都找不到原因。最后看帧长分布才发现这个业务是小包高频交互型平均帧长只有200多字节。前面算过每个以太网帧有固定开销前导码、帧间隙、帧头、FCS帧越短固定开销占比越高。200字节的帧有效载荷率可能只有70%出头再加上TCP/IP头应用层有效速率就更低了。这个坑的教训是吞吐量问题要先看业务流量特征。大文件传输和小包交互同样的链路跑出来的有效速率天差地别。抓包里用统计→长度分布一眼就能看出帧长集中在哪个区间。如果小包占比高别急着怀疑链路先确认业务本身是不是就该这样。4.2 抓包工具自己也会成为瓶颈高吞吐场景下抓包工具本身可能丢包导致你抓到的丢包是假的。判断方法看抓包文件的帧序号有没有跳变或者看Wireshark的捕获统计里有没有dropped计数。如果有丢包抓包结果就不可信得换更轻量的抓包方式命令行工具、专用抓包设备或者降低抓包范围。我一般在高吞吐场景优先用命令行抓包写文件再用Wireshark离线分析。离线分析不影响抓包过程也不会因为Wireshark实时解析拖慢抓包。另外抓包时尽量只抓目标流过滤器在抓包阶段就生效别抓全量再过滤那样丢包风险高得多。4.3 时间同步没做好两端对比就是自欺欺人两端抓包对比的前提是时间戳可比。如果两台机器时钟不同步你算出来的单向延迟全是错的。我吃过这个亏两端时钟差了几十毫秒算出来的单向延迟离谱到没法看差点把排查方向带到沟里。解决办法抓包前用时间同步机制把两端时钟对齐到毫秒级以内或者干脆用一台机器同时抓双向比如在中间镜像口抓避免跨机时间对比。如果只能用两端抓包至少记录下两端的时钟偏差分析时做补偿。Wireshark本身有时间参考功能可以把一个包设为参考点后续包显示相对时间但跨文件对比还是得靠绝对时间对齐。4.4 别忽略应用层和协议栈之间的那道缝有时候抓包看TCP层一切正常窗口够、RTT低、无重传但应用层吞吐就是上不去。这时候问题往往在应用层和协议栈之间应用读数据太慢、缓冲区设置不合理、或者协议栈参数比如发送缓冲、接收缓冲没调优。抓包能看到的只是协议栈发出/收到了什么看不到应用层处理得多快。要定位这类问题得结合应用侧日志和系统指标比如socket缓冲使用率、CPU占用。我的经验是TCP层指标全部正常但吞吐上不去八成是应用层或系统配置的问题抓包到这里就可以收手转去查应用和系统了。5. 把排查流程固化成一张可复用的清单5.1 从现象到根因的判断路径踩的坑多了我总结出一条相对固定的判断路径每次排查按这个顺序走能少走很多弯路看全局形态IO Graph看吞吐曲线形态平稳/锯齿/断崖先分类。看异常事件分布tcp.analysis统计重传、零窗口、乱序各占多少。算理论上限窗口除以RTT和实测对比判断差距量级。查窗口看计算后的窗口值区分通告窗口小、cwnd小、应用读得慢。查RTT看ack_rtt曲线区分路径延迟和排队延迟。查重传看重传类型和分布区分超时、快速、spurious。查流量特征帧长分布判断是否小包开销导致。查应用与系统TCP层正常但吞吐低转查应用和系统配置。这条路径不是死的实际排查中经常需要来回跳但有个固定顺序能保证不漏项。尤其是新手最怕的就是东看一点西看一点最后啥也没定位到。5.2 几个高频误判的对照表抓包现象常见误判实际可能原因窗口字段显示6万多窗口太小是瓶颈没看缩放因子实际窗口可能很大有重传就是链路丢包链路质量差可能是乱序触发的spurious重传吞吐锯齿状链路不稳定拥塞控制正常调整或周期性重传抓包看到丢包网络真丢包抓包工具自身丢包帧序号跳变可验证单向延迟异常大路径有问题两端时钟不同步时间戳不可比这张表里的每一条我都在实际排查中遇到过至少一次。尤其是第一条和第五条坑了不止一回。新手拿到抓包文件先对照这张表排除掉这些误判能省掉大量无效分析。5.3 抓包之外还得看什么抓包是手段不是目的。有些问题抓包根本看不到比如网卡硬件卸载TSO、GRO导致抓到的包和实际发出的包不一致比如虚拟化环境里虚拟交换机内部的转发行为比如无线链路的空口竞争。这些场景下抓包结果可能具有误导性得结合设备计数、系统指标、甚至专用测试工具交叉验证。我的原则是抓包负责回答TCP层发生了什么设备计数负责回答链路层发生了什么系统指标负责回答主机内部发生了什么。三者对不上说明有某一层的信息缺失或者被干扰得先把信息补齐再下结论。单靠抓包下结论翻车的概率不低。最后分享一个我自己的习惯每次排查完把抓包文件、分析结论、最终根因整理成一个小案例存档标注好关键过滤器和判断依据。下次遇到类似现象直接翻存档对照比从头分析快得多。这个习惯坚持下来排查速度会肉眼可见地提升因为大部分新问题其实都是老问题的变种。
RELATED

相关推荐

Linux VM内核参数调优:内存管理、脏页回写与OOM实践

Linux VM内核参数调优:内存管理、脏页回写与OOM实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/23 4:01:39
【跟踪】跟踪篇(4)--对于MOT16 Benchmark的理解

【跟踪】跟踪篇(4)--对于MOT16 Benchmark的理解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/23 4:01:39
STM32F103与AT24C02的I2C读写实战:时序、硬件与调试避坑指南

STM32F103与AT24C02的I2C读写实战:时序、硬件与调试避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/23 4:01:39
MORE NEWS

更多资讯

📰

FairScan Scan-to-PDF Intent开发指南:让你的应用调用隐私优先的扫描器

【免费下载链接】FairScan An Android app to scan your documents — simple and respectful 项目地址: https://gitcode.com/gh_mirrors/fa/FairScan 点击查看 免费下载 FairScan 是一个开源的 Android 文档扫描应用,主打「简单、尊重用户」&#xff…

📰

30分钟刷好平衡车FOC固件:hoverboard-firmware-hack-FOC 实战指南

30分钟刷好平衡车FOC固件:hoverboard-firmware-hack-FOC 实战指南 【免费下载链接】hoverboard-firmware-hack-FOC With Field Oriented Control (FOC) 项目地址: https://gitcode.com/GitHub_Trending/ho/hoverboard-firmware-hack-FOC 那台嗡嗡响、起步发愣…

📰

WoWee路线图前瞻:从大灾变支持到全新MMO计划,这个开源实验将走向何方

【免费下载链接】WoWee World of Warcraft Engine Experiment - a custom opensource client. 项目地址: https://gitcode.com/gh_mirrors/wow/WoWee 点击查看 免费下载 WoWee 是一个基于 C20 与 Vulkan 1.3 渲染器的开源魔兽世界客户端,目前已支持 Van…

📰

手把手教程:从零到平衡车 FOC 电机控制,一次讲透 hoverboard-firmware-hack-FOC

手把手教程:从零到平衡车 FOC 电机控制,一次讲透 hoverboard-firmware-hack-FOC 【免费下载链接】hoverboard-firmware-hack-FOC With Field Oriented Control (FOC) 项目地址: https://gitcode.com/GitHub_Trending/ho/hoverboard-firmware-hack-FOC …

📰

Rufus 制作 Win11 安装盘教程:3 步绕过 TPM 2.0

Rufus 制作 Win11 安装盘教程:3 步绕过 TPM 2.0 【免费下载链接】rufus The Reliable USB Formatting Utility 项目地址: https://gitcode.com/GitHub_Trending/ru/rufus Rufus 是一款单文件绿色 U 盘格式化工具,最大本事是把 Windows 11 安装器里…

📰

从0.5.x迁移到0.6:Unreal_mcp单一unreal工具革命完全指南与直接调用移除处理

【免费下载链接】Unreal_mcp A comprehensive Model Context Protocol (MCP) server that enables AI assistants to control Unreal Engine through the native C Automation Bridge plugin. Built with TypeScript and C. 项目地址: https://gitcode.com/gh_mirro…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬