性能与扩展基础
latency vs throughput、垂直/水平扩展。
性能与扩展基础
这一课你将能做到
- 区分延迟、吞吐、并发三个指标,并知道各自用什么数字观测(P99 / QPS / 并发数)
- 用 Little's Law 对本站任意接口算出「目标 QPS 下需要多少线程/连接」
- 针对具体瓶颈,按「代码 → 缓存 → 读写分离 → 分片」的成本顺序给出扩展方案
为什么要学
用户说「系统慢」,运维说「系统撑不住」——这是两个完全不同的问题,对应性能(Performance) 和可扩展性(Scalability)。搞混它们,优化就会做错方向:该加缓存的时候加机器,该异步的时候死磕 SQL。
面试里这是开场送分题也是送命题:「延迟和吞吐有什么区别?」「系统从 1000 QPS 扩到 10000 QPS 你怎么做?」答不出层次感,后面的深挖基本没机会。
人话:性能是「单个请求跑多快」(你点外卖 30 分钟到手),扩展性是「订单翻 10 倍还跑不跑得动」(一万个骑手同时抢单系统崩不崩)。优化性能是消除浪费,提升扩展性是消除单点。
先建立图像
三个指标各自量什么:
| 指标 | 含义 | 观测方式 | 本站例子 |
|---|---|---|---|
| 延迟 Latency | 单次请求耗时 | P50 / P99 / P999 | 题目详情页打开 180ms |
| 吞吐 Throughput | 单位时间处理量 | QPS / TPS | 列表页扛 800 QPS |
| 并发 Concurrency | 同一时刻在处理数 | 活跃线程/连接数 | 判题同时跑 300 个沙箱 |
三者由 Little's Law 锁死:并发数 = QPS × 平均耗时。判题 30 QPS × 10 秒 = 300 并发槽,这条公式在本站被验证了两次:一次是判题池容量,一次是 Tomcat 线程数。
可用性也有「月亮数字」:
99.9% → 全年故障 8.76 小时 (三个 9,普通业务底线)
99.99% → 全年故障 52.6 分钟 (四个 9,核心交易)
99.999% → 全年故障 5.26 分钟 (五个 9,成本翻几倍,慎承诺)
再背一张延迟基准表(估算全靠它):
内存随机读 ~100ns
Redis 一次读写 ~0.5ms(机房内)
MySQL 主键查询 ~1-5ms(命中 buffer pool)
SSD 随机读 ~100μs-1ms
机房内网络 RTT ~0.5ms
跨地域 RTT ~30ms+
扩展只有两条路:
垂直扩展 Scale Up:8C16G → 16C32G → 32C64G
优点:不改代码;缺点:有物理上限、价格非线性(规格翻倍价格×3)
水平扩展 Scale Out:1 个 Spring Boot 实例 → N 个实例 + Nginx
优点:理论上无限加;缺点:要求无状态,引入 LB/分布式复杂性
跟着做
步骤 1:压测本站接口,拿到真实基线
用 wrk 压题目列表接口(JMeter/ Gatling 同理):
# 4 线程、保持 100 个连接、压 30 秒
wrk -t4 -c100 -d30s http://localhost:8080/api/problems?page=1&size=20
输出里重点看三行:Requests/sec(吞吐)、Latency Distribution 的 99%(P99)、Socket errors(有没有非 2xx)。假设结果:QPS 900、P99 220ms——这就是基线,写进监控看板。
步骤 2:用 Little's Law 做容量规划
目标:列表接口要扛 5000 QPS、P99 保持在 200ms 以内。