性能与规模 — 单个请求要快,整个系统要扛得住¶
这一章讲什么: 前六章管 API 长什么样,这一章管它跑不跑得动。书里把问题劈成两半: 性能=单个请求有多快;规模=请求数涨上去之后还能不能保持这个快1。 两半的答案风格完全不同:性能靠「逐层削减冗余」——压缩、过滤、分页,每一刀都有算术; 规模靠「把活分出去」——从单机加配置到多机加实例,每一步都有取舍。 读完你能回答:为什么 Gzip 能压掉一大半、为什么越加配置越不划算、什么时候该拆微服务。
1. 顶层全景:三层优化,然后一次架构分叉¶
性能(单请求) 规模(多请求)
───────────────────── ──────────────────────────
① 压缩:把响应体本身变小 ④ 纵向扩容:单机加配置
② 过滤:别发没用的字段 → ⑤ 横向扩容:加机器 + 负载均衡
③ 分页:集合切成小份 ⑥ 架构:单体 ⇄ 微服务
图说:①②③是把每一次传输里的水分挤掉;④⑤⑥是当挤无可挤时,
把负荷摊到更多硬件上。前者的尽头是后者的起点。
先交代本章的数字口径。原书的压测表(§5 会逐张过)是教学演示数据——原书没有说这些数字来自真实系统,我们按「示意」读:量级关系(翻倍资源换不来翻倍的吞吐——吞吐就是单位时间处理的请求数)是可信的,具体数值不可当容量规划依据。另外本章会反复出现 RPS(Requests Per Second,每秒请求数):1,000 RPS 就是每秒处理一千个请求。
本章的主线例子:一个 JWT 令牌服务的扩容实验¶
后半章的骨架是一个贯穿实验:一个用 Java 写的 JWT 令牌服务(对外提供两个端点:/issue 签发令牌、/verify 验签),单个实例每客户端占内存约 3 MB,目标是扛住 1,000 个客户端、1,000 RPS2。
实验路线(每一站一张表,数字逐站记):
2 核 2G 单机 → 4 核 4G → 8 核 8G ← 纵向:同一台机器加配置
2 实例 + 负载均衡 → 4 实例 → 10 实例 ← 横向:同样配置的多台机器分摊流量
图说:同一个服务、同样的活,两种加法。对照六张表,你会亲眼看到
「收益递减」和「近线性增长」分别长什么样。
前半章的性能三招(压缩、过滤、分页)则用另一个场景贯穿:一个用户资料端点 GET /users/123 返回 50 个字段,一个图书集合 /books 可能有几千条记录——客户端真的需要那么多吗?
2. 压缩:Gzip 凭什么把 JSON 压掉一大半¶
解决什么问题¶
响应体是在网络上传的数据;数据越少,传得越快,带宽(网络单位时间能传多少数据,俗称网速)也越省。REST API 的响应是 JSON 文本,而文本充满了重复(键名、结构符号、重复的单词)——重复就是压缩的粮食。书里先给结论:一套好的压缩办法能把大载荷压到接近原来的一半;对 JSON 通常能压掉 60–80%3。
Gzip 的两个阶段,拿一个 15 字节的例子逐位算¶
Gzip = LZ77 + Huffman 编码,两个阶段各管一种重复。原书的演示例子小到 15 个字符,正好把机制照得透亮4:
第一阶段:LZ77,消灭「重复的串」。 原始数据 HelloHelloWorld,15 个字节:
原始: H e l l o H e l l o W o r l d (15 字节)
压缩: Hello(5,5)World
(5,5) 的读法:往回数 5 个字符,把那里的 5 个字符复制过来。
第二个 Hello 没再写一遍,只写了一个 5 字节的「去前面取」标记(行话叫指针)。
图说:15 字节 → 13 字节。书里给的比方:老师批卷子,同样的错不重复写评语,
第一次写全,后面只写「见第一条」——指针比全文小得多。
第二阶段:Huffman 编码,消灭「重复的单字」。 统计压缩后文本里每个字符出现的次数,出现多的给短码、出现少的给长码:
| 字符 | 次数 | 分配的码 | 码长 |
|---|---|---|---|
| l | 3 | 00 | 2 位 |
| o | 2 | 01 | 2 位 |
| 5 | 2 | 10 | 2 位 |
| ( ) , | 各 1 | 1100 / 1101 / 1110 | 4 位 |
| H e W r d | 各 1 | 11110 / 11111 / 10000 / 10001 / 10010 | 5 位 |
把 Hello(5,5)World 按这张码表逐字符替换:104 位(13 字节)→ 51 位(6.375 字节),51% 的缩减5。两个阶段接力:LZ77 删「串」级重复,Huffman 删「字」级重复——合起来,JSON 里成片的 "id"、"name"、"email" 键名和括号引号全被压成了短码和「去前面取」标记,这就是 JSON 压缩率特别高的原因6。
怎么启用:一对头的协商¶
压缩不是默认开的,要客户端开口要。请求带 Accept-Encoding: gzip, deflate(告诉服务器「我能解这两种」),服务器回 Content-Encoding: gzip 加二进制体7:
请求: GET /api/users/123 HTTP/1.1
Accept-Encoding: gzip, deflate
响应: HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 153
[二进制 GZIP 数据...]
图说:协商遵循 REST 的无状态约束——客户端每次把能力说全,服务器不用记谁是谁;
网关和 CDN(内容分发网络,缓存静态资源的分布式节点)还能在中间再压一道。
CPU 的账:压缩不是白来的,LZ77 扫重复、Huffman 建码表都要耗 CPU。书里的经验线:小响应(1 KB 以下)压缩是亏的(CPU 开销换不来多少带宽);大响应才值。另外,对已经压缩过的格式(jpeg、zip、mp4)再压是白费 CPU——压不动还得陪着耗。客户端侧解压也有成本,低功耗移动设备上表现为更慢的渲染和更费的电池;于是有 Brotli 这类「同样压缩率、更低 CPU」的新办法可选。判据一句话:带宽省下的钱 > 两端 CPU 烧掉的钱,才开压缩8。
3. 过滤与分页:别把没用的东西发出去¶
解决什么问题:over-fetching(过度取回)¶
压缩管「字节怎么变少」,但有一个它管不了的问题:响应里装的东西本来就不该发。书里的定义:客户端要 5 个字段、你给了 50 个,就是过度取回——即使压缩过,无用的字段照样耗带宽、耗 CPU、占并发。书里给的典型:用户资料端点返回 50 个字段、界面只显示 5 个,90% 是白发的9。
字段过滤:让客户端点名¶
办法简单到一句话:URL 上加个参数,客户端列出要的字段:
GET /users/123?fields=id,name,email
图说:响应从 50 字段瘦身到 3 个。书里给的收益区间:50%–90% 的体积缩减;
数据库侧也随之减负——查询只 SELECT 点名的列,而不是整行拖回来。
按百万次调用累积,每次省几毫秒,攒出来的是小时的机器时间。
这就是第 04 章「可适配」那条标尺的性能版:参数化不仅为了适配不同客户端,更是为了少传10。
分页:把书架切成窗口¶
集合端点(GET /books 可能有几千条)绝不能一次全给。分页是把长书架切成窗口,每次只露一截。两个参数控制窗口:limit(窗口里放几本)和 offset(从第几本开始)。原书用 A–Z 当书架走了一遍11:
书架: [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, …, Z]
/books?limit=5&offset=0 → [A, B, C, D, E]
/books?limit=5&offset=5 → [F, G, H, I, J]
/books?limit=3&offset=12 → [M, N, O]
图说:offset 数的是「从头数第几本」,limit 是「拿几本」——两个旋钮,各管各的。
offset 的病:数据一动,窗口就漂。 假设你翻到 offset=5(窗口对准 F),这时有人在队首插入了一本 X,书架变成 [X, A, B, C, D, E, F, …];你的 offset=5 再翻页,拿到的就是 [E, F, G, H, I]——F 重复了,E 倒跳回来了。插入、删除都会让 offset 失准,这就是分页时的页漂移问题12。
cursor 的病根拔除。 办法是把「从头数第几本」换成「从某本书之后开始」——cursor(游标)就是一枚书签,钉在具体某本书上:
代价(我们补):cursor 要求集合有一个稳定排序,且客户端不能「跳到第 42 页」,只能一页页往后翻——深翻页场景(跳到最后一页)反而适合 offset。
分页的收尾细节¶
两个细节书里点得很有经验:一是服务器要设上限——客户端要 limit=10000 也得给压回最大值,防止无界查询把后端打爆;二是到头要说清楚——给出动态的 next/previous 链接,用 204 No Content 表示「没了」,别让客户端反复试探一个不存在的下一页。无限滚动那个「顺滑」的假象,底下就是这么一套尺寸刚好的分页13。
排序:先排好,再切窗¶
最后一个旋钮:分页切窗之前,可以让客户端定顺序。sort=-title 的减号表示逆序——GET /books?sort=-title&limit=4 把书架倒过来,先拿到 [Z, Y, X, W]。想先看到「最新」或「最便宜」的客户端,不用盲翻第一页14。
4. 性能小结:三层刀法的账¶
原始响应 ──Gzip──> 字节级:删重复(字符串+字符两种) 省 60–80%(JSON)
──字段过滤──> 内容级:只发点名的字段 省 50–90%(视冗余度)
──分页+排序──> 批量级:每次只发一页、按要的方式 把无界变有界
图说:三刀不冲突,是叠加的。但都救不了「请求数本身在涨」——那是下一节的事。
5. 规模:同一个服务的六张压测表¶
性能三招挤干单次传输后,真正的考试是并发量。书里用主线例子(JWT 令牌服务)做了两组对照实验,我们按站点逐张过。每个实例 2 核 2 GB、每客户端约 3 MB 内存、单线程 worker 进程,目标是 1,000 客户端 / 1,000 RPS15。
纵向扩容:翻倍资源,换不来翻倍吞吐¶
| 站点 | 配置 | 撑得住的客户端数 | 峰值 RPS | 错误率 |
|---|---|---|---|---|
| 参照起点 | 2 核 2 GB | 100(100 客户端时 CPU 已 100%) | 100 | 25%(100 客户端时) |
| 第一次升级 | 4 核 4 GB | 500 | 1,800 | 18%(500 客户端时) |
| 第二次升级 | 8 核 8 GB | 1,000 | 5,500 | 12%(1,000 客户端时) |
三张表连起来看,收益递减写得清清楚楚:第一次升级,资源翻倍,扛住的客户端从 100 到 500(5 倍,很香);第二次升级,成本再翻倍,同客户端数下的吞吐只从 3,200 涨到 4,200(1.3 倍)——钱花出去了,曲线却越来越平。而且每一站的尽头都是同一幕:CPU 顶到 100%,错误率开始冒头16。
更要命的是书里点破的第二件事:单点故障。所有蛋都在一个加固了的篮子里——这台加满了配置的机器一崩,整个服务全灭。书里对纵向扩容的判词:「买到的是时间,不是韧性;是丰裕,不是弹性」17。
横向扩容:加机器,把活摊开¶
第二组实验:配置退回 2 核 2 GB,改玩数量。前面架一个负载均衡器(load balancer,把进来的请求轮流分发给后端实例的机器),后面复制同样的实例:
| 站点 | 实例数 | 客户端数 | 峰值 RPS | 单实例 CPU | 错误率 |
|---|---|---|---|---|---|
| 单实例(纵向极限) | 1 | 100 | 600 | 100% | 25% |
| 加负载均衡 | 2 | 200 | 1,200 | 80% | 0% |
| 再翻一倍 | 4 | 500 | 3,000 | 75% | 5% |
| 目标达成 | 10 | 1,000 | 6,000 | 65–85% | 2% |
和纵向对照,差异刺眼:从 1 到 2 台,吞吐翻倍;2 到 4,再近翻倍;4 到 10,增速放缓但仍把错误率从 5% 压到 2%。书里对「放缓」的解释也诚实:负载在 10 台之间分得不均匀(CPU 在 65–85% 之间飘),最可能是负载均衡器的锅;单实例内存从 200 MB 微涨到 220 MB——即使「半无状态」的服务,同步共享数据(keystore)也有缓存成本18。
横向的本质收益书里总结为两点:没有单机天花板(加机器就行);没有单点——任何一台崩了,负载均衡器把流量引开,服务不停。这就是「弹性」(fault tolerance):多出来的容量本身就是容错19。代价同样说透了:监控、让多台机器协同部署这些运维杂事急剧变多——没有自动化,玩不转多台机器20。
6. 架构分叉:单体与微服务,不是优劣是取舍¶
扩容之争必然走到一个岔路口:单体(monolith,一个统一部署的整体应用)还是微服务(microservices,拆成许多独立部署的小服务)?书里的定性很准:这是哲学分歧——中央集权求控制,还是分权求演化21。
单体:凝聚力换弹性¶
单体的好处全是「一」:一份代码库、一次部署、调试不用跨服务追踪、事务不用 saga 那套分布式补偿、内存 CPU 共享。小团队、流量可预测时,这种简单是美德22。但单体和纵向扩容一样有自己的天花板:一个模块的 bug 拖垮整个系统(书里写得很形象:认证模块崩了,全站陪葬);流量涨 20% 就成了单点;合并部署日越来越可怕。书里给的分裂信号值得背:当加人不再提速(人月不再神话)、故障和流量增长开始相关,就是考虑拆的时候23。
怎么拆书里也给了路线:从最少被调、边界最清晰的服务开始抽,抽出去一个就在它和单体之间换成 REST 调用,全程保持向后兼容;负载均衡可以逐步切流、可回滚。一次抽一点,最后剩个「混合架构」,直到中心化 control 的残余全部让位给分散部署24。
微服务:弹性换复杂度¶
微服务反着来:系统被拆成各自自治的小服务,各自独立伸缩。主线例子的 JWT 服务若做成微服务,就是「认证单独成一个服务,藏在 API 网关后面,实例横向复制,状态卸载到共享 keystore」。坏实例不修了,直接换一个;网关把流量引走25。
代价书里一排比句:网络调用取代方法调用;最终一致性取代 ACID 事务;可观测性需要分布式工具链。ACID 是数据库事务的四个性质(原子、一致、隔离、持久),跨服务的分布式事务保证不了这么强,只能接受「数据暂时不一致、稍后一致」的最终一致性。微服务「扩得轻松,但要求设计和运维上的严格纪律」——组织扛不住这个纪律,微服务会从解药变成灾难26。
判断(书里给的框架,不是我们发明的): 问题从来不是「哪个架构更好」,而是「哪套取舍和这个系统的生命周期匹配」。书里的原话:单体以凝聚换弹性,微服务以团结换自由度;要中心化控制,还是去中心化演化27。
7. 作者的判断与证据¶
- 唯一的「实验」是六张压测表——但它们是教学演示,不是可复现的基准:没有说明测试环境、压测工具、测量方法。我们全部按「示意数据」处理,方向性结论(成本越涨收益越慢 vs 加机器近乎翻倍、共享状态有成本、负载可能不均)符合分布式系统的普遍经验,可信;数值不可引。
- Gzip 的逐位演示是本章最硬的内容:15 字节 → 13 字节 → 6.375 字节的每一步可亲手复算,Huffman 码表逐行可核——这是全书少见的「可验证」段落28。
- 「性能与规模互为表里」的总结是作者的判断,表述为「高效的单次调用对真实世界毫无意义,如果它不能在每秒数千次执行下成立」——这个把性能优化贬为「战术」、把架构贬为「战略」的框架,是本章真正的论点29。
- 书里没讲的(留白):缓存(第 03/05 章的主角)在规模里的位置、CDN 的角色、数据库这一层的扩展(读写分离、分片)、以及自动扩缩容(k8s 那一层)。六张表全在应用层打转,这是本章视野的边界。
8. 边界与局限¶
- 压测数字不可当容量规划依据(见 §7);真实容量必须在自己的栈上压测得出。
- cursor 分页的适用前提(稳定排序、不支持深跳页)书里只字未提,只给了「稳」的优点。
- 「微服务 vs 单体」一节是理念层面的,服务边界的划分方法(DDD、按团队拓扑)、分布式事务的具体方案(saga、outbox)都没展开——想实操要另找资料。
- Brotli 只在 CPU 权衡处一句带过,没有给选用判据。
- 排序参数的注入风险(
sort=-title这类自由文本参数直接拼进查询是注入攻击的老窝)书里完全没提——自己实现时这是安全坑。
9. 可带走的¶
本章主线例子一行走完: JWT 令牌服务,2 核 2 GB 单机到 100 个客户端就 25% 错误率;加配置到 8 核,错误率只是推迟到 1,000 客户端时重现,而第二笔硬件钱只买来 1.3 倍吞吐;改横向,2 实例错误率归零,10 台 2 核小机器稳稳扛住 6,000 RPS、错误率 2%——同样的预算,加法不一样,结局不一样。
- 性能三刀的顺序:先砍内容(过滤、分页——不发才最省),再砍字节(Gzip),顺序反了会白压一堆本来不用发的数据。
- Gzip = LZ77 删串级重复 + Huffman 删字级重复;JSON 因重复多吃到 60–80% 的压缩率。
- 压缩有 CPU 账:1 KB 以下别开,jpeg/zip/mp4 别压,移动端弱网弱电要权衡。
- 分页上限必须有,offset 会漂(数据变动时),cursor 像书签一样稳但要求稳定排序。
- 纵向扩容:快、零改动、有天花板、单点故障——是止痛药不是解药。
- 横向扩容:加机器近乎翻倍地涨、有韧性,但把复杂度换成运维账——没有自动化就别上量。
- 「半无状态」也有状态成本:实例间同步共享数据(keystore)的内存与一致性开销,会在表里显形(200→220 MB)。
- 拆单体的信号:加人不提速、故障随流量涨;拆法:从冷门、边界清的服务开始,逐次替换、全程可回滚。
- 单体 ⇄ 微服务是生命周期匹配问题:组织纪律扛不住分布式复杂度时,单体是美德不是落后。
10. 原文地图¶
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 性能 vs 规模的定义 | Performance and Scale | text/14-fm-introduction.txt:35(搜「finite resources」) · :632(搜「Vertical scaling」) |
| Gzip 总体效果 | Performance and Scale | text/14-fm-introduction.txt:70(搜「nearly half」) · :428(搜「60-80%」) |
| LZ77 演示 | Performance and Scale | text/14-fm-introduction.txt:79(搜「HelloHelloWorld」) · :85(搜「LZ77」) |
| Huffman 码表与 51% | Performance and Scale | text/14-fm-introduction.txt:88(搜「Huffman coding」) · :380(搜「Table 7.1」) · :383(搜「51%」) |
| LZ77 老师批卷类比 | Performance and Scale | text/14-fm-introduction.txt:479(搜「grading multiple papers」) |
| 压缩协商头 | Performance and Scale | text/14-fm-introduction.txt:485(搜「Accept-Encoding」) · :503(搜「gzip, deflate」) · :515(搜「Content-Encoding」) |
| CPU 权衡与 1KB 线 | Performance and Scale | text/14-fm-introduction.txt:530(搜「under 1KB」) · :533(搜「Brotli」) |
| over-fetching 与 50 字段例 | Performance and Scale | text/14-fm-introduction.txt:539(搜「50 fields」) |
| 字段过滤与 50–90% | Performance and Scale | text/14-fm-introduction.txt:548(搜「fields=id,name,email」) · :551(搜「50-90%」) |
| 分页 offset/limit 与 A–Z 例 | Performance and Scale | text/14-fm-introduction.txt:560(搜「offset」) · :569(搜「A, B, C」) · :572(搜「offset=0」) |
| 页漂移问题 | Performance and Scale | text/14-fm-introduction.txt:590(搜「off by one」) |
| cursor 书签方案 | Performance and Scale | text/14-fm-introduction.txt:593(搜「cursor」) · :599(搜「cursor=K」) |
| 分页上限与 204 | Performance and Scale | text/14-fm-introduction.txt:557(搜「maximum limit」) · :611(搜「204 No Content」) |
| 排序 sort=-title | Performance and Scale | text/14-fm-introduction.txt:623(搜「sort=-title」) |
| JWT 服务设定(3MB/客户端、目标) | Performance and Scale | text/14-fm-introduction.txt:716(搜「3 MB per client」) · :719(搜「1,000 tokens」) |
| 纵向三张表 | Performance and Scale | text/14-fm-introduction.txt:722(搜「2-core CPU」) · :823(搜「Doubling resources quadruples」) · :924(搜「5,500 RPS」) · :1025(搜「1.3x more throughput」) |
| 纵向:单点故障与「买到时间」 | Performance and Scale | text/14-fm-introduction.txt:1028(搜「single point of failure」) · :638(搜「buys time」) |
| 横向与负载均衡 | Performance and Scale | text/14-fm-introduction.txt:1041(搜「load balancer」) |
| 横向三张表 | Performance and Scale | text/14-fm-introduction.txt:1120(搜「throughput doubles」) · :1193(搜「3,000 RPS」) · :1266(搜「6,000 RPS」) · :1339(不均与 keystore 成本) |
| 运维复杂度指数上升 | Performance and Scale | text/14-fm-introduction.txt:1342(搜「exponentially」) |
| 单体:优势与天花板 | Performance and Scale | text/14-fm-introduction.txt:1354(搜「single, unified edifice」) |
| 拆分信号与拆法 | Performance and Scale | text/14-fm-introduction.txt:1363(搜「diminishing returns」) · :1366(搜「Extract the least used services」) |
| 微服务:代价排比 | Performance and Scale | text/14-fm-introduction.txt:1379(搜「Network hops replace method calls」) |
| 结论:战术与战略 | Performance and Scale | text/14-fm-introduction.txt:1388(搜「tactics and strategy」) |
-
出处:「CHAPTER 7 Performance and Scale」第 35 段(
text/14-fm-introduction.txt:35,搜「Performance focuses attention」)。原文:「Performance focuses attention on the transmission of data through compressed payloads... Scale requires foresight.」性能与规模的区分贯穿全章,第 632 段再次对照:「API performance optimization attends to the speed and responsiveness of single API calls... Scale ensures that APIs maintain this responsiveness even as the number of clients grows exponentially.」 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 716 段(
text/14-fm-introduction.txt:716,搜「3 MB per client」)与第 719 段(text/14-fm-introduction.txt:719,搜「1,000 tokens」)。原文:服务用 RSA256 算法签发与验证 JWT;「the memory requirements for a single instance of the token service is about 3 MB per client」;基线要求「to issue/verify 1,000 tokens (requests) per second while scaling up to 1,000 clients」。两个端点的请求/响应示例见第 647–713 段。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 70 段(
text/14-fm-introduction.txt:70,搜「nearly half」)与第 428 段(text/14-fm-introduction.txt:428,搜「60-80%」)。原文:「On average, a good compression algorithm dwarfs a large payload into an equivalent that is nearly half its original size」;「a two-stage compression approach typically reduces JSON text by about 60-80%」。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 79 段(
text/14-fm-introduction.txt:79,搜「Original: HelloHelloWorld」)与第 85 段(text/14-fm-introduction.txt:85,搜「LZ77」)。原文:「Scanning for repetitive sequences in text and replacing them with directives is achieved through an algorithm called LZ77 or Lempel Ziv, named after the inventors Abraham Lempel and Jacob Ziv in 1977.」15 字节→13 字节的计算见同段。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 88 段(
text/14-fm-introduction.txt:88,搜「Huffman coding」)、第 380 段(text/14-fm-introduction.txt:380,搜「Table 7.1」)、第 383 段(text/14-fm-introduction.txt:383,搜「51% reduction」)。原文:「Through Huffman coding, the 13 bytes in the LZ77 output, Hello(5,5)World, shrinks down to just 6.4 bytes, for a 51% reduction in size」;104→51 位的分解见第 386–424 段。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 428 段(
text/14-fm-introduction.txt:428,搜「JSON compresses particularly well」)。原文:「LZ77 stage of compression picks up on repeated strings, id, name, email, role, and replaces all of them with compact pointers to a single, original instance of the string.」老师批卷的类比见第 479 段。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 485 段(
text/14-fm-introduction.txt:485,搜「Accept-Encoding」)、第 503 段(text/14-fm-introduction.txt:503,搜「gzip, deflate」)、第 515 段(text/14-fm-introduction.txt:515,搜「Content-Encoding」)。原文:「the absence of an explicit compression preference through headers, disables it」;「The Accept-Encoding and Content-Encoding headers follow REST's uniform interface constraint」。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 530 段(
text/14-fm-introduction.txt:530,搜「under 1KB」)与第 533 段(text/14-fm-introduction.txt:533,搜「Brotli」)。原文:「CPU overhead is difficult to rationalize for responses under 1KB... Applying compression to compressed file formats such as jpeg, zip, and mp4, wastes CPU」;「other algorithms like Brotli offer higher compression ratios at a much lower compute cost on certain payloads」;「what helps a data center may strain an IoT device」。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 539 段(
text/14-fm-introduction.txt:539,搜「50 fields」)。原文:「a user profile request from a client that returns 50 fields but only displays 5, a response that amounts to 90% over-fetching, which saturates networks and bogs down CPUs」。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 545 段(
text/14-fm-introduction.txt:545,搜「fields of interest」)与第 551 段(text/14-fm-introduction.txt:551,搜「50-90%」)。原文:「A parameter that accepts a list of fields to include in the response gives clients granular control」;「the performance benefit of field-filtered payloads typically falls into a range of 50-90% reduction in size」。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 557 段(
text/14-fm-introduction.txt:557,搜「sliding viewport」)与第 560 段(text/14-fm-introduction.txt:560,搜「offset and limit」)。原文:「pages act like a sliding viewport (a window) on a long, unbroken bookshelf」;窗口的两个旋钮:「its size (limit)... It also moves by a distance (offset)」。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 590 段(
text/14-fm-introduction.txt:590,搜「off by one」)。原文:「Say if someone inserts X in front of the data set, then after the second request, offset=5 lands on [E, F, G, H, I], off by one. This page shifting problem also happens if letters are removed during pagination.」 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 557 段(
text/14-fm-introduction.txt:557,搜「maximum limit」)与第 611 段(text/14-fm-introduction.txt:611,搜「204 No Content」)。原文:「the server should always enforce a maximum limit, using it as a safeguard value whenever the client's requested limit exceeds it」;「Dynamic next and previous links, and a 204 No Content HTTP status can notify clients when they have reached the end」。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 623 段(
text/14-fm-introduction.txt:623,搜「sort=-title」)与第 626 段(text/14-fm-introduction.txt:626,搜「flips the bookshelf」)。原文:「A client can retrieve the last four books by sorting in reverse-alphabetical order and taking the first page」。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 722 段(
text/14-fm-introduction.txt:722,搜「2-core CPU」)。原文:「Initial resource allocation: 2-core CPU/2 GB RAM (AWS t3.small equivalent). At baseline, the service handles 100 RPS smoothly but fails under 100 clients, hitting CPU limits and a 25% error rate」。三张纵向表的数值我们按原书照抄:表 7.2(基线)、表 7.3(4 核)、表 7.4(8 核)。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 823 段(
text/14-fm-introduction.txt:823,搜「Doubling resources quadruples throughput」)、第 924 段(text/14-fm-introduction.txt:924,搜「5,500 RPS」)、第 1025 段(text/14-fm-introduction.txt:1025,搜「1.3x more throughput」)。原文:「after the first vertical upgrade, the service scales up to 2x the number of users, through a 2x increase in resources. But after a second upgrade for 2x the hardware costs, the service only yields 1.3x more throughput」。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 638 段(
text/14-fm-introduction.txt:638,搜「abundance without resilience」)与第 1028 段(text/14-fm-introduction.txt:1028,搜「single point of failure」)。原文:「Vertical scaling buys time, but rarely endures over the long haul. It is abundance without resilience」;「if the beefed-up server fails, the entire system collapses」。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 1120 段(
text/14-fm-introduction.txt:1120,搜「throughput doubles」)、第 1193 段(text/14-fm-introduction.txt:1193,搜「3,000 RPS」)、第 1266 段(text/14-fm-introduction.txt:1266,搜「6,000 RPS」)、第 1339 段(text/14-fm-introduction.txt:1339,搜「65% and 85%」)。原文:「The load is unevenly distributed, so it causes CPU variance between 65% and 85% across instances. The most likely culprit is the load balancer. Memory overhead per instance goes up, slightly, from 200MB to 220MB due to shared keystore synchronization, a reminder that even semi-stateless services carry cache costs.」 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 1041 段(
text/14-fm-introduction.txt:1041,搜「no single failure spells complete disaster」)。原文:「No single server has full responsibility, so no single failure spells complete disaster」;「the overcapacity makes the whole system more resilient」见第 1339 段。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 1342 段(
text/14-fm-introduction.txt:1342,搜「exponentially」)。原文:「operational complexity increases exponentially... the system's monitoring and deployment orchestration become burdensome... demands some form of automation to manage a distribution」。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 1348 段(
text/14-fm-introduction.txt:1348,搜「philosophical divide」)。原文:「This tension between the two models betrays a philosophical divide in systems architecture: to centralize for control or decentralize for evolution」;「the question is not which architecture is better, but which trade-offs align with a system's lifespan」。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 1354 段(
text/14-fm-introduction.txt:1354,搜「single, unified edifice」)。原文:「A monolith is a single, unified edifice where all components are tightly coupled, sharing memory, CPU, and fate... For early-stage systems, or those with predictable loads, this level of simplicity is a virtue... A crashed authentication module tanks the entire system. Monoliths scale until they cannot.」 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 1363 段(
text/14-fm-introduction.txt:1363,搜「diminishing returns」)。原文:「When adding more engineers yields diminishing returns, and outages correlate directly with traffic expansion, then it is time to consider something different.」 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 1366 段(
text/14-fm-introduction.txt:1366,搜「Extract the least used services」)。原文:「start by analyzing service traffic patterns. Extract the least used services with well-defined boundaries... while maintaining backward compatibility throughout the migration. Load balancers can distribute traffic incrementally, and performance can be tracked, with the possibility of roll backs if needed.」 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 1379 段(
text/14-fm-introduction.txt:1379,搜「A failed instance is replaced, not repaired」)。原文:「As a microservice, the JWT token service would scale up by isolating authentication behind an API gateway, and by replicating instances horizontally while offloading state to a shared keystore.」 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 1379 段(
text/14-fm-introduction.txt:1379,搜「Network hops replace method calls」)。原文:「Network hops replace method calls. Eventual consistency supplants ACID transactions. Observability demands intricate distributed tooling... They scale with ease but demand rigorous discipline, in design and operation.」 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 1348 段(
text/14-fm-introduction.txt:1348,搜「monoliths favor cohesion」)。原文:「monoliths favor cohesion, they trade elasticity for unity. Microservices, by contrast, revel in fragmentation. They turn down unity for degrees of freedom.」 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 85 段(
text/14-fm-introduction.txt:85,搜「15 bytes」)与第 383 段(text/14-fm-introduction.txt:383,搜「6.4 bytes」)。两阶段的每一步数值(15→13→6.375 字节、104→51 位)均可按原书表格复算。 ↩ -
出处:「CHAPTER 7 Performance and Scale」第 1388 段(
text/14-fm-introduction.txt:1388,搜「tactics and strategy」)。原文:「Performance and scale do not operate independently. They engender an exchange between tactics and strategy. An efficient API call means very little to real-world adoption if it cannot accommodate thousands of executions per second on a whim.」 ↩