KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA

05 · 观测驱动的性能优化闭环 — keel 龙骨

这一章回答:怎么把"系统有点慢"变成一个有数据、有顺序、可验收的工程过程。

这一章回答:怎么把"系统有点慢"变成一个有数据、有顺序、可验收的工程过程。

性能优化最容易变成玄学:大家凭感觉改,改完也不知道有没有效。把它变成闭环,核心是三件事:先有基线,再做单点变更,最后用同一套指标验证。

一、闭环五步

测量基线 → 定位瓶颈 → 单点优化 → 灰度验证 → 记录复盘

每一步的要求:

步骤 要求 常见错误
测量基线 确定观测对象与工具,先记录优化前的数字 还没测就开始改
定位瓶颈 用数据收敛到一处(慢 SQL?外部依赖?序列化?) 同时怀疑七八个地方
单点优化 一次只改一处,能独立回滚 一次提交里改五处,事后不知道哪个生效
灰度验证 先小流量(10%)观察,再放量 直接全量上线
记录复盘 写下前后数据与结论 优化完就散了,下次重来

二、要看哪些指标

应用层(接口维度):

指标 为什么
P50 / P95 / P99 平均值会被极少慢请求拉偏或被大量快请求掩盖;看 P99 才有意义
错误率与非 2xx 分布 优化不应以错误率上升为代价
QPS 与并发数 判断是容量问题还是单请求性能问题

依赖层:

指标 健康信号
数据库慢查询数量 / 索引命中率 见第 01 章
锁等待时长、死锁次数 见第 02 章
连接池使用率 持续接近上限说明容量不足
缓存命中率 ≥95%(热点场景)
MQ 堆积量与消费延迟 持续增长说明消费能力不足
下游依赖 P99 与错误率 决定是否需要熔断/降级

资源层: CPU、内存、磁盘 IO、网络。多数"数据库慢"最后查出来是磁盘 IO 打满。

三、区分两类指标:资源指标 vs 目标指标

一个实用提醒:CPU、内存这类是资源指标,用来排查;而延迟、错误率、吞吐这类是目标指标,用来判断好不好。这两者经常被混淆。

四、压测:验证而不是表演

wrk -t4 -c100 -d60s http://localhost:8000/api/orders       # 固定并发打一段时间
locust -f locustfile.py --headless -u 500 -r 50 -t 3m      # 逐步加压

三条纪律:

  1. 一次只变一个变量(并发数、数据量、开关),否则无法归因;
  2. 跑到系统饱和为止,画出"QPS - 延迟 - 错误率"随并发变化的三条曲线,拐点就是容量上限;
  3. 压测环境要接近生产(数据量级、索引、配置),否则结果没有参考价值。

典型的发现:延迟在某个并发点之后陡升而 QPS 不再增长——这个点就是系统的实际承载上限,也应该是限流阈值的设定依据(见《后端高并发》第 03 章)。

五、一份优化记录应该长什么样

【现象】订单列表接口 P99 1.2s,超过目标 500ms
【定位】EXPLAIN 显示 type=ALL;慢日志中该 SQL 占总耗时 68%
【改动】添加联合索引 (tenant_id, status, created_at),改为覆盖索引
【验证】灰度 10%:P99 1.2s → 280ms;全量后 DB CPU 下降 35%
【副作用】写入耗时 +3ms(可接受),索引磁盘 +400MB
【回滚方案】DROP INDEX idx_tenant_status_created
【下次】该表数据量达 N 万时重新评估索引有效性

注意其中两栏:副作用与回滚方案。缺少它们的优化记录是不完整的——任何优化都是在交换某种代价。


动手:可观察结果

产出 判断标准
三条压测曲线 QPS-延迟-错误率随并发的变化图,标出拐点
一次完整优化记录 包含上面七个字段,尤其是副作用与回滚方案
一个核心看板 至少有:接口 P99、错误率、DB 慢查询数、缓存命中率、MQ 堆积
一次灰度演练 10% 流量验证后再全量的完整过程

完成标志:给定一个"系统变慢"的报告,你能在不看代码的情况下,通过看板把范围收敛到某一类资源或某一个依赖。

故障注入

注入方式 观察
只优化不测量 事后能否说出这次改动带来了多少提升(通常说不出)
一次改五处 出问题后能否定位是哪一处导致的
跳过错峰直接全量 优化有副作用时的影响面
压测环境与生产数据量级差异巨大 结论是否在生产失效
只看平均响应时间 P99 问题是否被均值掩盖

自测题

  1. 为什么优化要一次只改一处?给出两个理由。
  2. 平均响应时间掩盖了什么问题?为什么看 P99?
  3. 资源指标与目标指标的区别是什么?告警应该挂在哪一类?
  4. 压测的"拐点"意味着什么?它和限流阈值的关系是什么?
  5. 为什么优化记录里必须写副作用和回滚方案?举一个你经历过的反例。

进入 keel 阅读