文档目录
导论
本章定位:全书的世界观。不装工具、不搭环境,只解决一件事——让你在动手之前就知道自己在测什么、测出来的数字能不能信。
前置知识:无(能读懂 Kotlin 即可) 预计总时长:约 3 小时(阅读 2 小时 + Lab 0 约 1 小时) 配套代码:
docs/code/00-introduction/
一、本章要回答的六个问题
读完本章,你应该能不查资料地回答:
- 老板说「接口太慢了」,你第一句话该问什么?(第 1 节)
- 为什么「又快又省资源」是不存在的,优化的本质到底是什么?(第 2 节)
- 为什么平均值会骗人,后端为什么必须盯住 P99?(第 3 节)
- 一个 QPS 500、延迟 20 ms 的服务,需要多大的连接池?(第 4 节)
- 为什么 CPU 跑到 90% 不是「还剩 10%」,而是「延迟已经涨了 9 倍」?(第 5 节)
- 为什么市面上很多压测报告的 P99 是假的?(第 6 节,本章最重要)
二、为什么第 0 章不讲工具
你已经学过 C++ 并发,对「性能」有肌肉记忆:关心缓存行、内存序、伪共享、分支预测。这些能力很有价值,但它们建立在两个前提上:
- 前提一:你测的东西是稳定的(同一段代码跑一万次,耗时w基本一样)。
- 前提二:你测的东西不会被运行时改掉(编译器不会把你的计算删掉)。
在后端 + JVM 的世界里,这两个前提都会失效:
| 你的 C++ 经验 | 后端的现实 |
|---|---|
| 编译产物固定,性能可预测 | JIT 边跑边优化,性能随时间变化,前 30 秒和后 5 分钟是两个系统 |
| 测单函数就能代表它 | 瓶颈常常在排队、连接池、GC、下游,而不在你优化那行代码里 |
| 没有 GC,延迟靠代码决定 | GC 停顿会让 P99 出现周期性尖刺,与你的代码无关 |
| 工具测出来的就是真相 | 大多数压测工具会系统性低估尾延迟(第 6 节的协调遗漏) |
所以顺序必须是:先纠正观念 → 再学测量 → 最后才学工具。工具学错了可以换,观念错了会一直用错误的数据做决策。
本章就是你后面所有实验的「标尺」:第 3 章开始搭环境、第 5 章开始做记录、第 6 章开始定位瓶颈,如果没有本章的观念,你会得到一堆漂亮但错误的数字。
三、小节地图
| 节 | 标题 | 一句话内容 | 时长 | 要动手 |
|---|---|---|---|---|
| 1 | 三类问题必须分开处理 | 微基准 / 负载测试 / 性能剖析,问的是三个不同的问题 | 15 min | — |
| 2 | 吞吐、延迟、成本的三方权衡 | 没有「全面更快」,只有「拿什么换什么」 | 15 min | — |
| 3 | 延迟是分布,不是数字 | 均值是谎言的载体;尾延迟会跨服务放大 | 25 min | ✅ 模拟 |
| 4 | 用 Little’s Law 估算容量 | 一个小学除法,算出你需要多少连接/线程/协程 | 25 min | ✅ 计算器 |
| 5 | 为什么 90% 利用率已经很危险 | 排队是非线性的,这是留冗余的数学依据 | 25 min | ✅ 模拟 |
| 6 | 协调遗漏:压测报告的最大谎言 | 闭环压测会藏起最慢的那一秒 | 30 min | ✅ 模拟 |
| 7 | 九条常见谬误自查清单 | 对照检查你现在的做法踩了几条 | 15 min | — |
| 8 | 性能工程闭环 | 八个步骤,以及为什么它是循环而非流程 | 15 min | — |
| 9 | 从 C++ 到 JVM:哪些直觉必须修正 | 哪些经验仍然成立,哪些必须推翻 | 20 min | — |
| 10 | Lab 0:先被骗一次 | 亲手测出物理上不可能的数字 | 60 min | ✅ 实验 |
建议节奏:每节读完先做节末的「自测」,答不上来就回去重读那一节。第 3–6 节建议配合代码跑一遍——这四节的理论,跑一次模拟比读十遍管用。
四、本章的产出物
学完本章你不写业务代码,但必须交出三样东西:
- 一份实验记录体系(已建好,见
docs/experiments/README.md)——它会一直用到第 9 章。 - E00 实验档案:Lab 0 的记录,格式照
docs/experiments/_TEMPLATE/example-lab0.md。 - 两个待测接口的初步目标:写下它们的预期 QPS 与可接受的 P99。写不出具体数字,说明第 1 章必须先学。
五、学完本章的验收标准
- 能对着一个模糊的性能抱怨,说出该用哪一类方法去测,以及为什么不用另外两类。
- 能解释「为什么 P99 合格但用户体验仍然很差」。
- 能在不查资料的情况下写出 Little’s Law,并用它算出连接池大小。
- 能解释「90% 利用率」为什么危险,以及容量规划为什么要留 30%–50% 余量。
- 能指出一份压测报告中「P99 不可信」的三个信号。
- Lab 0 能跑出荒谬数字,并且你能说清它为什么荒谬。
本节目录
- 三类问题必须分开处理 0.1 三类问题必须分开处理 上一节:无(这是全书的起点) | 下一节:0.2 吞吐、延迟、成本的三方权衡 配套代码 …
- 吞吐、延迟、成本的三方权衡 0.2 吞吐、延迟、成本的三方权衡 上一节:0.1 三类问题必须分开处理 | 下一节:0.3 延迟是分布,不是数字 一句话结论 「让性能变好」是一句没有意义 …
- 延迟是分布,不是数字 0.3 延迟是分布,不是数字 上一节:0.2 吞吐、延迟、成本的三方权衡 | 下一节:0.4 用 Little’s Law 估算容量 配套代码 …
- 用 Little's Law 估算容量 0.4 用 Little’s Law 估算容量 上一节:0.3 延迟是分布,不是数字 | 下一节:0.5 为什么 90% 利用率已经很危险 配套代码 …
- 为什么 90% 利用率已经很危险 0.5 为什么 90% 利用率已经很危险 上一节:0.4 用 Little’s Law 估算容量 | 下一节:0.6 协调遗漏:压测报告的最大谎言 配套代码 …
- 协调遗漏 0.6 协调遗漏:压测报告的最大谎言 上一节:0.5 为什么 90% 利用率已经很危险 | 下一节:0.7 九条常见谬误自查清单 配套代码 …
- 九条常见谬误自查清单 0.7 九条常见谬误自查清单 上一节:0.6 协调遗漏:压测报告的最大谎言 | 下一节:0.8 性能工程闭环 用法:拿你现在项目里的做法,逐条对照。踩了 3 …
- 性能工程闭环 0.8 性能工程闭环 上一节:0.7 九条常见谬误自查清单 | 下一节:0.9 从 C++ 到 JVM:哪些直觉必须修正 一句话结论 性能工作不是一个「上线 …
- 从 C++ 到 JVM 0.9 从 C++ 到 JVM:哪些直觉必须修正 上一节:0.8 性能工程闭环 | 下一节:0.10 Lab 0:先被骗一次 一句话结论 你从 C++ 并发 …
- Lab 0 0.10 Lab 0:先被骗一次 上一节:0.9 从 C++ 到 JVM:哪些直觉必须修正 | 下一节:第 1 章 指标与目标 配套代码 …