惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
MyScale Blog
MyScale Blog
Y
Y Combinator Blog
罗磊的独立博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
V
Vulnerabilities – Threatpost
T
The Blog of Author Tim Ferriss
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
N
News and Events Feed by Topic
B
Blog RSS Feed
阮一峰的网络日志
阮一峰的网络日志
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 【当耐特】
N
Netflix TechBlog - Medium
博客园 - 叶小钗
B
Blog
Vercel News
Vercel News
T
Tenable Blog
T
The Exploit Database - CXSecurity.com
Spread Privacy
Spread Privacy
T
Threat Research - Cisco Blogs
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Last Week in AI
Last Week in AI
F
Fortinet All Blogs
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Microsoft Security Blog
Microsoft Security Blog
S
Securelist
Microsoft Azure Blog
Microsoft Azure Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Palo Alto Networks Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
D
DataBreaches.Net
Cyberwarzone
Cyberwarzone
Engineering at Meta
Engineering at Meta
Martin Fowler
Martin Fowler
G
GRAHAM CLULEY
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
A
Arctic Wolf
C
CERT Recently Published Vulnerability Notes
L
LangChain Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Check Point Blog
A
About on SuperTechFans
W
WeLiveSecurity
The GitHub Blog
The GitHub Blog

卡瓦邦噶!

服务器高性能网络调优 | 卡瓦邦噶! 为何写作 | 卡瓦邦噶! 读《金阁寺》 | 卡瓦邦噶! 雨季又来 | 卡瓦邦噶! 3.5 秒的固定延迟问题 | 卡瓦邦噶! 学习网络的一点经验 | 卡瓦邦噶! ARP 问题诊断 | 卡瓦邦噶! 网络断断续续…… | 卡瓦邦噶! Piccolo P2P 镜像分发 | 卡瓦邦噶! 一起看电影 | 卡瓦邦噶! 《征服C指针》 | 卡瓦邦噶! 我的姥姥 | 卡瓦邦噶! WordPress网站迁移方案 Python的哲学 Python 3.5的新特性 学校不教的计算机课 垃圾回收(GC)的三种基本方式 在编程中体验纯粹的快乐 从《美丽新世界》谈自由 在快钱实习 迷人的嗓音和迷人的故事——《Sleepyhead》 Python 的十个自然语言处理工具 记一个愚蠢的bug 一年炉石传说的游戏体验 《以撒的结合:重生》网页版图鉴 分清 C++的指针、引用和数组 笑话三则 自由比皇帝更伟大——《悲惨世界》笔记 Git 10 周年访谈:Linus 讲述背后故事 用 0x3f3f3f3f 设定最大int值的优点 Joel给计算机系学生的建议 一个词法分析器的简单实现 怎样才算健康的生活方式 MacVim 配置攻略 学习培训课程的视频效果好吗? 语言的控制 可悲的大多数 CSS样式思维导图 2014年终总结 奥巴马成为首位写程序的美国总统 青岛老城区的下水道好在哪里? 做优秀 UI 的七个建议(第二部分) 选择爱情的骑士 Git简明教程 Java集合总览 读 《1984》 java问答:终极父类(六)——等待/唤醒和接口 Java 问答:终极父类(五)——toString() Hyperlapse快速视频背后的技术细节 平庸之恶 Java程序员须知的七个日志管理工具 苏州 逛书摊随想 关于考试作弊 你的工作不仅仅是编程 推荐在线学习Java的英文资源 关注女性命运——《千禧年三部曲》 用好你的幻灯片——《演说之禅》 使用ReentrantLock和Lambda表达式让同步更纯净 新手学编程,从哪里开始? 程序员都是工程师吗? 不要学习代码,要学会思考 Java 问答:终极父类(四)——hashCode() Java 问答:终极父类(三)——finalize()和 getClass() 程序员职业之路的选择 我是一名摄影家 写给何小树的城市指南 为什么一些语言会比别的快? Java的常见误区与细节 跟朋友在一起玩游戏 死神永生——读《三体》 五种类型的程序员 创业圣经——读《黑客与画家》 纪念加西亚·马尔克斯 Junit中处理异常的另一种方式:catch-exception Java8采用Martin Fowler的方法创建内部DSL Linux HotSopt虚拟机GC线程的CPU占用率 J2EE概念介绍 如何成为一名黑客 Java 问答:终极父类(二)——equals()方法 为什么我喜欢Java Java 问答:终极父类(一)——clone()方法 七个改变世界的Java项目 java中默认类型转换的小问题 传统与创新 欢迎来到互联网 莫言和马尔克斯——读《生死疲劳》 位运算的妙用 读《人为什么活着》 写博客教会我的事情 中国特色操作系统 2013年总结 《永不妥协》影评 恨不相逢未嫁时——《廊桥遗梦》影评 如何优雅地使用PPT 给明年依然年轻的我们 天才与柱子 黑客守则和黑客精神 Looking for Freedom——《被解救的姜戈》 简洁之道
MTU Probe 引起的初始延迟 | 卡瓦邦噶!
laixintao · 2026-03-17 · via 卡瓦邦噶!

答案是 MTU 设置错误1,链路可以发送的最大 MTU 小于 1500 bytes,但是客户端侧配置的 MTU 却是 1500 bytes。所以 TCP 连接建立之后的包,无法到达另一端。在等待 3.5s 左右,发送端觉得链路存在问题,尝试降低发出的包的大小,这时候就可以发过去了,链路上才开始数据传输。

要定位这个问题,我们现在抓包文件中,找到传输数据最多的那个 TCP flow,就是传输数据最多的那个。这个连接是我们重点研究的对象。右键选择 Follow > TCP Stream,来只展示这一个会话。(如何追踪某一个 TCP 流,在前面 重新认识 TCP 的握手和挥手2 中也介绍过)。

TCP connection 建立之后,客户端一下发了 10 个包,大小都为 1500 bytes。但是服务端一个都没有 ACK。

前10个包都没有得到服务端的 ACK,前两个包也可以看到 TCP 两端协商的 MSS 是 1460 bytes

然后客户端开始重传。

前 3 次重传分别发生在 0.3s, 0.8s, 1.7s,也都没有收到 ACK。

第 4 次重传发生在 3.5s 这个包不再以 1500 bytes 发送了,而是 1076 bytes (TCP 层是 1024 bytes) 发送。这个包得到了服务端的 ACK。

第 4 次重传降低了 MTU,并且收到了 ACK

于是客户端知道,1076 bytes 的包可以被服务端收到,所以后续都用 1076 bytes 作为 MTU 发送。过一段时间之后尝试更大的包,1288 bytes,1394 bytes,发现也没有被 drop,就继续 probe 并且增大 MTU,最后用 1399 bytes,接近链路的真实 MTU (实际链路 MTU 是 1400 bytes)。

这就是每一个连接都会卡 3.5s 的原因。

为什么要重传 3 次才开始降低 MTU 呢?

这是通过 tcp_retries1 设置的。man 是这么说的:

The number of times TCP will attempt to retransmit a packet on an established connection normally, without the extra effort of getting the network layers involved. Once we exceed this number of retransmits, we first have the network layer update the route if possible before each new retransmit. The default is the RFC specified minimum of 3.

即 TCP 会尝试 tcp_retries1 次数的重传,而不涉及 IP (network) layer.

如果超过了 tcp_retries1 还没有重传成功的话,(默认第 4 次)就会认为链路存在异常了,需要 IP 层接入,比如开始 mtu probe 尝试解决问题。

如果设置为 1,那么在卡的时间就会降低到 1s 左右。(当然,最好的解决方式还是设置正确的 MTU)。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

# sysctl -w  net.ipv4.tcp_retries1=1                                                                                                                                                                                            

net.ipv4.tcp_retries1 = 1

# iperf3 -c 10.0.2.2 -b 10M

Connecting to host 10.0.2.2, port 5201

[  5] local 10.0.1.2 port 54580 connected to 10.0.2.2 port 5201

[ ID] Interval           Transfer     Bitrate         Retr  Cwnd

[  5]   0.00-1.00   sec  0.00 Bytes  0.00 bits/sec    2   1.41 KBytes

[  5]   1.00-2.00   sec   128 KBytes  1.05 Mbits/sec   22   15.7 KBytes

[  5]   2.00-3.00   sec  3.50 MBytes  29.4 Mbits/sec    2    150 KBytes

[  5]   3.00-4.00   sec  1.25 MBytes  10.5 Mbits/sec    0    200 KBytes

[  5]   4.00-5.00   sec  1.12 MBytes  9.44 Mbits/sec    0    200 KBytes

[  5]   5.00-6.00   sec  1.25 MBytes  10.5 Mbits/sec    0    200 KBytes

[  5]   6.00-7.00   sec  1.12 MBytes  9.44 Mbits/sec    0    200 KBytes

[  5]   7.00-8.00   sec  1.25 MBytes  10.5 Mbits/sec    0    200 KBytes

[  5]   8.00-9.00   sec  1.12 MBytes  9.44 Mbits/sec    0    200 KBytes

[  5]   9.00-10.00  sec  1.25 MBytes  10.5 Mbits/sec    0    200 KBytes

- - - - - - - - - - - - - - - - - - - - - - - - -

[ ID] Interval           Transfer     Bitrate         Retr

[  5]   0.00-10.00  sec  12.0 MBytes  10.1 Mbits/sec   26             sender

[  5]   0.00-10.02  sec  12.0 MBytes  10.0 Mbits/sec                  receiver

iperf Done.

而根据 TCP 的重传时间,大概就是在 3.5s 左右了。

前面说,第 4 次重传的包是从 1076 bytes 开始发送,为什么是这个数字呢?

这个是 sysctl 参数 net.ipv4.tcp_base_mss = 1024 控制的。TCP payload 是 1024 bytes,加上 TCP 的 header,就是 1076 bytes 了。

如果读者尝试复现这个例子,会发现在 MTU 设置错误的情况下,会一直卡住。这是因为 MTU 出现问题的时候,默认的工作机制是靠 ICMP 消息 “Fragmentation Needed” (Type 3, Code 4 in IPv4) 来提示需要降低 MTU 的。但是现实情况中,这个 ICMP 一般是收不到的(因为各种设备为了所谓的「安全问题」丢弃了 ICMP),这样就会出现 blackhole,一直重试缺卡在这里。默认情况下,MTU 错误的设置地大了,是会一直卡住的。

但是可以通过 sysctl 参数设置 net.ipv4.tcp_mtu_probing,默认是 0,即不用 probe。

如果是 1 的话,在出现 blackhole 的时候就会尝试降低 segment 的大小看能不能通。即本文中的情况。

如果是 2,是一直启用,即 TCP 不管对方说的 MSS,发送的时候总是从一个小的 MSS 开始发,如果没有问题,再逐渐加大。

MTU 常见的原因,以及一些其他的相关讨论,可以参考下面列出来的 有关 MTU 和 MSS 的一切 一文。

  1. 有关 MTU 的详细分析,可以参考之前的文章:有关 MTU 和 MSS 的一切 ↩︎
  2. 重新认识 TCP 的握手和挥手:答案和解析 ↩︎

==抓包破案录==

这篇文章是抓包破案录系列文章(之前叫做《计算机网络实用技术》,后来改名了)中的一篇,这个系列正在连载中,我计划用这个系列的文章来分享一些网络抓包分析的实用技术。这些文章都是总结了我的工作经历中遇到的问题,经过精心构造和编写,每个文件附带抓包文件,通过实战来学习网络抓包与分析。

如果本文对您有帮助,欢迎扫博客右侧二维码打赏支持,正是订阅者的支持,让我公开写这个系列成为可能,感谢!

如果您正在阅读的是题目类的文章,这个目录内容正好用来隔离其他读者的评论。读完题目可以稍作暂停,进行思考,继续向下滑动,可能会被其他的读者剧透答案。

没有链接的目录还没有写完,敬请期待……

  1. 序章
  2. 抓包技术以及技巧
  3. 理解网络的分层模型
  4. 数据是如何路由的
  5. 网络问题排查的思路和技巧
  6. 不可以用路由器?答案和解析
  7. 网工闯了什么祸?答案和解析阅读加餐!
  8. 重新认识 TCP 的握手和挥手答案和解析
  9. 3.5 秒初始延迟问题答案和解析
  10. 网络断断续续……答案和解析
  11. 延迟增加了多少?答案和解析
  12. 压测的时候 QPS 为什么上不去?答案和解析
  13. TCP 下载速度为什么这么慢?答案和解析
  14. 请求为什么超时了?答案和解析
  15. 0.01% 的概率超时问题答案和解析
  16. 后记:学习网络的一点经验分享
与本博客的其他页面不同,本页面使用 署名-非商业性使用-禁止演绎 4.0 国际 协议。