从架构师视角看"三高":度量、设计与权衡
本文面向中高级后端工程师与架构师,非权威文档,仅表达个人观点供参考。
假设读者已了解基本的数据库、缓存、消息队列概念,不重复解释基础术语。
重点不是"是什么",而是"怎么量、怎么选、怎么权衡"。
一、架构师为什么要重新理解"三高"
"高并发、高可用、高性能"是面试和简历的高频词,但真正做过容量规划、故障演练和架构评审的人都知道,这三个词解决的是完全不同维度的问题:
- 高并发 :大量请求同时涌入时,系统能否承接------关注并发数 和排队。
- 高可用 :部分组件故障时,系统能否持续服务------关注冗余 和故障转移。
- 高性能 :单位请求处理得够不够快、资源效率是否合理------关注响应时间 和吞吐量。
三者相互关联,但优化手段和代价截然不同。架构师的核心能力,是能针对具体业务场景,在这三者之间做出合理的权衡,并用数据验证决策。
二、度量体系:架构决策的数据基础
架构设计不能凭感觉,所有决策必须建立在可度量的指标之上。以下按四个维度梳理。
2.1 性能维度
响应时间与分位数
响应时间(RT)是单次请求的全链路耗时。平均值在架构决策中几乎没有参考价值------它会被大量正常请求拉低,掩盖长尾。
假设 10000 个请求中 9900 个耗时 1ms,100 个耗时 100ms,平均仅 1.99ms。但每 100 个用户就有 1 个要等 100ms。P99 才反映长尾用户的真实体验。
类比:全班 50 人平均分 85 分,但有一个 0 分。平均分掩盖了问题,P99 暴露了问题。
P999 在金融、电信级系统中必须纳入监控------0.1% 的慢请求在 1000 万日请求量下就是每天 1 万次异常,可能触发连锁故障。
怎么确定目标?
- 测当前:APM 监控或网关日志,排序计算分位数。
- 找上限:压测梯度法,P99 急剧恶化时即接近极限。
- 定目标:普通查询 P95<200ms、P99<500ms;核心交易 P95<100ms、P99<300ms;秒杀 P95<50ms、P99<200ms。
QPS 与 TPS
QPS 是每秒请求数,TPS 是每秒完整事务数。一个事务可能包含多次查询,因此 QPS ≥ TPS。
类比:点菜是 1 次事务(TPS),服务员去厨房问 4 次是 4 次查询(QPS)。
架构决策中必须关注峰值 QPS:
峰值 QPS = 日请求量 ÷ 86400 × 峰值因子(通常取 2.5)
例如日请求 21 万次 → 平均 QPS 2.45 → 峰值 QPS 约 6.1。这个数字看着小,但如果个别 SQL 执行 93 秒,并发积压会飙升至数百,系统依然会被拖垮。
吞吐量
吞吐量 = 单位时间内成功完成的请求数。与 QPS 的区别:QPS 统计"发起",吞吐量统计"完成"。
吞吐量与响应时间存在经典权衡:单条处理延迟低但吞吐低,攒批处理延迟高但吞吐高。消息队列的"攒批"机制就是牺牲单条延迟换取整体吞吐。
类比:每有一个包裹就立刻送一趟,响应快但一天送不了多少;攒 50 个再送,单个等待变长但一天能送 5000 个。
怎么确定吞吐量目标? 测当前(监控取成功请求数)→ 找上限(压测找拐点)→ 定目标(业务峰值量 ÷ 峰值持续时间)。系统最大吞吐量应 ≥ 业务峰值 × 1.5。
错误率与成功率
错误率决定系统是否"可用",也是熔断器触发的核心依据。核心交易错误率应 < 0.01%,普通查询 < 0.1%,非核心 < 1%。
2.2 可用性维度
可用性 N 个 9
| 等级 | 全年停机 | 典型场景 |
|---|---|---|
| 99% | 3.65 天 | 内部系统 |
| 99.9% | 8.76 小时 | 普通企业应用 |
| 99.99% | 52.6 分钟 | 互联网核心业务 |
| 99.999% | 5.26 分钟 | 金融、电信级 |
每提升一个 9,架构成本可能翻倍。架构师需要根据业务价值选择,而非盲目追求高可用。
RTO 与 RPO
- RTO:故障后多久能恢复服务。
- RPO:能容忍丢多少数据。
类比:写文档时电脑蓝屏,RTO 是多久能重新打开,RPO 是丢了多少内容。
怎么确定? 通过故障演练测实际恢复时间和数据丢失量,按业务容忍度定目标。普通业务 RTO<30 分钟、RPO<5 分钟;核心交易 RTO<5 分钟、RPO≈0;金融级 RTO<1 分钟、RPO=0。
2.3 资源维度
CPU、内存、磁盘 IO、网络带宽
瓶颈最终都会体现在某一层资源上。告警阈值:CPU>80%、内存>85%、磁盘 IO 等待>20%、网络带宽>70%。危险阈值:CPU>95%、内存>95%。
饱和度与排队长度
饱和度比利用率更敏感------利用率高不一定排队,但排队一定意味着瓶颈。
关键饱和度指标:连接池排队数、线程池队列长度、数据库活跃会话数。目标:排队数 = 0,活跃会话数 < 最大连接数的 80%。
GC 与运行时指标(Java 场景)
一次 Full GC 可能导致数秒停顿,直接拉高 P99。很多"偶发卡顿"的根因不是 SQL,而是 GC。
目标:P99 GC 暂停 < 100ms,Full GC < 1 次/小时,老年代使用率 < 70%。
2.4 一致性维度
复制延迟
主从架构中从库落后主库的时间。复制延迟过高会导致读到旧数据。普通查询 < 1 秒,核心业务 < 100ms,强一致场景直接读主库。
2.5 核心定律:利特尔法则
并发数 = QPS × 平均响应时间(秒)
这个公式是容量规划的基石。它揭示了两个关键结论:
- 提升吞吐量只有两条路径:降低 RT 或提升可承载并发数。
- 低并发也能导致系统卡死------如果 RT 足够大。
类比:超市 10 个收银台,每秒进来 3 个顾客。正常结账 10 秒,同时只有 0.3 个顾客在结账。但如果有个人结账要 93 秒,后面就会排长队。每秒进来的人没变,队伍却越来越长。
架构启示:排查卡顿时,先算并发数。如果 QPS 不高但系统卡顿,问题一定出在 RT 上,而不是流量。
三、压测:从指标到验证
3.1 QPS 压测
QPS = 总请求数 ÷ 总耗时。使用 JMeter、wrk 或 ab,设置并发梯度(10、50、100、200...),每个梯度运行 5-10 分钟,记录 QPS、RT、P95/P99、错误率,找到 QPS 不再上升的拐点。
3.2 TPS 压测
TPS 需要定义事务边界。应用层用 JMeter 事务控制器将完整业务链路定义为一个事务;数据库层用 sysbench:
bash
sysbench oltp_read_write --threads=64 --time=300 --report-interval=10 run
3.3 压测报告必须包含
| 类别 | 指标 |
|---|---|
| 吞吐 | QPS、TPS、成功吞吐量 |
| 延迟 | 平均 RT、P50、P95、P99、P999 |
| 质量 | 错误率、成功率 |
| 资源 | CPU、内存、磁盘 IO、网络带宽 |
| 饱和度 | 连接池排队数、线程池队列长度 |
| 运行时 | GC 暂停时间、GC 频率 |
| 一致性 | 主从复制延迟 |
只写"平均响应时间 83ms"的压测报告,在架构评审中是不合格的。
四、高并发设计
4.1 判断标准
并发数是否超过 CPU 核心数,是判断是否进入高并发挑战区的硬指标。
32 核服务器,并发数 < 32 时每个请求几乎独占核心;并发数远超 32 时,CPU 疲于上下文切换,性能急剧下降。
类比:32 个收银台,10 个顾客在结账很轻松,200 个顾客同时在结账就要来回切换、手忙脚乱。
关键提醒:高并发 ≠ 高 QPS。QPS 高但 RT=10ms,并发数=1;QPS 低但 RT=10s,并发数可能上百。
4.2 单机优化
异步化是单机优化的核心方向。Tomcat Servlet 本身基于多线程,在请求中再开辟线程池只会增加上下文切换。CompletableFuture 等异步机制能提高资源利用率。
4.3 集群扩展
- 无状态化:水平扩展的前提。
- 读写分离:读操作路由到从库。
- 数据分片:按规则拆分到多个节点。
- 多级缓存:客户端 → CDN → 反向代理 → 应用层 → 分布式缓存。
4.4 稳定性保障
- 限流:服务端保护自己不被压垮,令牌桶/漏桶/滑动窗口。
- 熔断:调用方保护自己不被拖死,失败率超阈值自动切断。
- 降级:故障时返回兜底数据,保核心业务。
限流像景区保安:"今天最多放 5000 人。"熔断像打电话连续 10 次没接,决定今天不打了。
五、高可用设计
5.1 冗余设计
应用层每个服务 ≥ 3 副本跨可用区;数据层 MySQL 主从、Redis Cluster、Kafka 多副本;机房级同城双活、异地多活。
备用节点就绪等级:
| 类型 | 状态 | 数据同步 | 切换 | RTO | RPO | 成本 |
|---|---|---|---|---|---|---|
| 热备 | 实时运行 | 实时/准同步 | 自动 | 秒级 | ≈0 | 高 |
| 温备 | 部分就绪 | 异步复制 | 手动 | 分钟级 | 秒级 | 中 |
| 冷备 | 不运行 | 定期备份 | 人工 | 小时级 | 天级 | 低 |
数据备份方式(注意与备用节点区分):
| 类型 | 备份时系统状态 | 业务可读写 | 典型方式 |
|---|---|---|---|
| 热备份 | 在线 | 可读写 | InnoDB 热备、RMAN |
| 温备份 | 在线但限制写入 | 只读/锁表 | mysqldump --lock-tables |
| 冷备份 | 停机 | 不可读写 | 停机拷贝文件 |
5.2 隔离设计
- 线程池隔离:核心与非核心业务独立线程池。
- 信号量隔离:轻量级,不额外增加线程池。
- 数据隔离:不同租户物理隔离。
类比:轮船密封舱,一个舱进水关上舱门,其他舱不受影响。
5.3 混沌工程
主动注入故障验证系统韧性。故障类型:Pod 终止、网络延迟/丢包、带宽限流、CPU 压力、节点关机。某金融企业每月 2 次演练,故障自愈率从 37% 提升至 82%,平均恢复时间缩短 65%。
类比:消防演习,不是等真着火才手忙脚乱。
六、高性能设计
6.1 空间换时间
缓存是最经典的实践。从 CPU L1/L2 到 Page Cache 到 Redis,每一层都在用存储换速度。重点解决穿透、击穿、雪崩。
6.2 分而治之
分库分表、微服务化、请求分批处理。
类比:100 斤箱子一个人搬吃力,两个人各搬 50 斤就轻松。
6.3 异步化与削峰填谷
消息队列将瞬时洪峰转化为匀速消费。
类比:水库上游暴雨先蓄水,下游按需放水,避免冲垮下游。
6.4 数据库性能优化
优先级:索引优化 > SQL 改写 > 读写分离 > 连接池优化。
类比:索引是书的目录。没有目录翻整本书,有了目录直接翻到对应页。一个缺失的索引,可能让数据库从"翻目录"变成"翻全书"。
七、三者的关系与权衡
7.1 相互关联
高性能直接提升高并发能力------请求处理更快,同样硬件承载更多并发。高可用保障高并发场景下的稳定性。
7.2 CAP 定理
分布式系统最多同时满足一致性(C)、可用性(A)、分区容错性(P)中的两项。
一致性:所有节点同一时刻看到相同数据。
类比:你和朋友看直播,你看到 2:1,朋友也必须看到 2:1。
可用性:任何时刻都能响应请求。
类比:随时打开 App 都能看到画面,哪怕画质模糊。
分区容错性:网络分区时系统仍能服务。
类比:北京和上海办公室网络断了,各自还能处理业务。
为什么 P 是必选项? 分布式系统中网络分区必然发生。因此只能在 C 和 A 之间取舍:
| 选择 | 含义 | 场景 |
|---|---|---|
| CP | 分区时拒绝服务,保一致 | 银行转账、库存扣减 |
| AP | 分区时继续服务,数据可能不一致 | 社交媒体、商品浏览、选号查询 |
7.3 BASE 理论
CAP 说"必须放弃强一致",BASE 说"具体怎么放弃":
- 基本可用:故障时损失部分可用性,如响应变慢、功能降级。
类比:餐厅满座让你等 10 分钟,而不是直接赶走。
- 软状态:允许中间状态存在。
类比:外卖订单先显示"商家已接单",再"骑手已取餐",最后"已送达"。
- 最终一致性:数据经过一段时间后最终一致。
类比:北京改了密码,上海过几秒才能用新密码,但最终会同步。
7.4 具体权衡
| 维度 | 选择 A | 选择 B | 决策依据 |
|---|---|---|---|
| 可用性 vs 一致性 | AP | CP | 是否容忍短暂不一致 |
| 延迟 vs 吞吐量 | 低延迟 | 高吞吐 | 用户对实时性的敏感度 |
| 性能 vs 可扩展性 | 单机极致 | 水平扩展 | 增长预期和成本 |
| 同步 vs 异步 | 同步 | 异步 | 是否要求实时返回 |
同一个系统不同链路可采用不同策略。
八、工程案例
8.1 射击成绩系统缓存优化
数万到数十万级并发读取,峰谷差两个数量级。通过时序特征和轻量级模型做热冷数据识别,毫秒级热点 key 预热;动态热点副本调度 + K8s Redis Cluster 自动扩缩容。
效果:峰值吞吐 30,000 → 86,000 QPS,P99 降低 62%,非高峰节省 43% 缓存资源。
8.2 电商大促缓存吞吐
缓存 QPS 从 5 万飙至 500 万。传统 Redis 单线程单节点 8-10 万 QPS,需 50+ 节点。Tair 多线程架构单节点 51 万 QPS。2025 双 11 实测:商品详情 55 万 QPS,库存计数 51 万 QPS,P99 从 1.8ms 降至 0.2ms。
8.3 从百到千万 QPS 演进
日活从几千暴涨到 50 万,首页 RT 从 200ms 飙到 8 秒。
- 第一阶段:三层缓存(CDN → Nginx+Lua → Redis),命中率 30%→95%,RT 8s→800ms。
- 第二阶段:微服务拆分 + Hystrix 熔断。教训:拆太细治理复杂度指数上升。
- 第三阶段:分库分表 16 库 8 表,ES 做二级索引。
- 第四阶段:RocketMQ 异步化。
启示:高并发架构是演进出来的,不是设计出来的。先止血、再拆解、然后分散压力、最后异步化。
8.4 秒杀系统多层防御
Nginx+Keepalived → Gateway 限流 → Caffeine 本地缓存 + 风控 → Redis Cluster Lua 原子扣减 → RocketMQ 异步落库 → MySQL 分库分表。
核心:读多写少全缓存;Redis 单线程保证原子性;预扣库存 + 异步落库实现最终一致。
九、常见认知误区
| 误区 | 真相 |
|---|---|
| 日活高 = 高并发 | 日活 100 万集中在 1 小时,QPS 仅几百 |
| QPS 高 = 高并发 | QPS 高但 RT 低,并发数可能只有 1 |
| 加机器 = 解决高并发 | 瓶颈在锁或慢 SQL,加机器无效 |
| 没故障 = 高可用 | 未经混沌验证的高可用只是侥幸 |
| 平均值 = 性能 | 平均值掩盖长尾,必须看 P99 |
十、架构师自查清单
| 维度 | 自查项 |
|---|---|
| 性能 | 峰值 QPS/TPS?P95/P99/P999?错误率?成功吞吐量? |
| 并发 | 峰值并发数?是否超过 CPU 核心数?限流阈值? |
| 可用性 | 几个 9?RTO/RPO?混沌演练频率? |
| 资源 | CPU/内存/IO/带宽使用率?连接池排队数? |
| 运行时 | GC P99?Full GC 频率? |
| 一致性 | 主从延迟? |
| 全局 | 瓶颈在哪一层?三高权衡策略是否明确? |
十一、总结
"三高"不是三个形容词,而是一套完整的工程体系:
- 度量:QPS、TPS、吞吐量、错误率、RT、P95/P99/P999、可用性 N 个 9、RTO/RPO、资源利用率、饱和度、GC、复制延迟。
- 设计:冗余、隔离、异步、缓存、分片、限流、熔断、降级、混沌工程。
- 理论:CAP 定理、BASE 理论、利特尔法则。
- 方法:用数据说话、用架构解决问题、用权衡做决策、用演练验证假设。
架构师的核心能力,不是记住多少技术名词,而是能针对具体业务场景,在"三高"之间做出合理的权衡,并用数据验证决策。
附录:术语表
性能指标
| 术语 | 解释 |
|---|---|
| QPS | 每秒查询数 |
| TPS | 每秒事务数 |
| RT | 响应时间 |
| P95/P99/P999 | 分位数,95%/99%/99.9% 请求快于该值 |
| 吞吐量 | 单位时间成功处理的请求数 |
| 错误率 | 失败请求占比 |
| 并发数 | 同时处理中的请求数 = QPS × RT |
| 峰值因子 | 平均 QPS 放大为峰值 QPS 的系数,常取 2~3 |
可用性与容灾
| 术语 | 解释 |
|---|---|
| N 个 9 | 可用性等级,如 99.9% 全年停机 ≤8.76 小时 |
| RTO | 恢复时间目标 |
| RPO | 恢复点目标 |
| 热备节点 | 备用系统实时运行,自动接管 |
| 温备节点 | 备用系统部分就绪,手动切换 |
| 冷备节点 | 备用系统不运行,人工恢复 |
| 热备份 | 在线备份,业务可读写 |
| 温备份 | 备份时业务只读或锁表 |
| 冷备份 | 停机备份 |
资源与运行时
| 术语 | 解释 |
|---|---|
| GC | 垃圾回收 |
| Full GC | 全量垃圾回收,导致 Stop-The-World |
| Stop-The-World | GC 时所有应用线程暂停 |
| 饱和度 | 资源等待队列长度 |
| 连接池排队数 | 等待获取数据库连接的请求数 |
一致性与理论
| 术语 | 解释 |
|---|---|
| CAP 定理 | 分布式系统最多同时满足 C、A、P 中的两项 |
| CP | 优先一致性和分区容错,故障时拒绝服务 |
| AP | 优先可用性和分区容错,允许短暂不一致 |
| BASE 理论 | AP 的工程实现:基本可用、软状态、最终一致性 |
| 最终一致性 | 数据经过一段时间后最终一致 |
| 复制延迟 | 从库落后主库的时间 |
工具与组件
| 术语 | 解释 |
|---|---|
| JMeter | 开源压测工具 |
| sysbench | 数据库 OLTP 压测工具 |
| APM | 应用性能监控,如 SkyWalking |
| Redis | 内存键值数据库,常用作缓存 |
| RocketMQ / Kafka | 分布式消息队列 |
| 混沌工程 | 主动注入故障验证系统韧性 |
本文面向中高级后端工程师与架构师,文中数据案例已脱敏,仅供技术交流。转载请注明出处。