【背景】
做了 10 年性能优化,最常被 PM 和产品同学问的一句话是:「这个接口 P99 从 42ms 降到 41ms,用户能感知到吗?这 3 天的开发时间是不是浪费?」
我经历过两种极端:
- 某电商大促前,一个商品列表接口 P99 是 180ms,团队花了一周把序列化从 JSON 换成 Protobuf,P99 降到 162ms,效果不错——但事后复盘发现,真正的瓶颈是下游库存服务的锁竞争,序列化只贡献了 4ms。
- 另一个案例更典型:一个内部 BI 报表接口 P99 是 2.3 秒,业务方说"能接受",于是没人动。但半年后数据量涨了 8 倍,P99 飙到 18 秒,临时抱佛脚加了缓存,结果缓存击穿那天直接拖垮了主库。
这两个案例让我开始认真思考:「值得优化」的判定标准到底是什么?
【常见分歧 / 几种做法】
我观察到团队里通常存在四派:
① "先量后优"派(Profile-driven) 没有火焰图、没有 APM 数据,一行代码都不动。追求 80/20 法则,只打最肥的那颗瓜。问题在于:如果最肥的瓜需要重构才能摘,这 20% 的成本怎么算?
② "架构优先"派(Architecture-first) 认为架构层面的优化(缩短调用链、减少数据搬运、消除 N+1)永远比微调参数(连接池大小、线程池队列长度)ROI 高。这个我基本认同,但"架构优化"往往意味着 2-4 周甚至更长的排期,短期内拿不到可量化的收益。
③ "SLO 驱动"派(SLO-driven) 只有 P99 超出 SLO 才启动优化,在 SLO 内"不动就是最优"。逻辑自洽,但有个根本问题:SLO 怎么定? 定太松(比如 P99 < 500ms),永远不优化,直到某天雪崩;定太紧(比如 P99 < 20ms),团队永远在优化,业务迭代停滞。
④ "成本敏感"派(Opportunity-cost) 3 天优化 1ms,不如 3 天做一个核心功能。这个观点在资源紧张时完全合理,但忽略了一个隐性成本:技术债的复利效应。一次"先欠着"的决策,半年后可能需要 3 周来还。
【我的倾向与理由】
我倾向 「SLO 驱动 + 架构优先」 的组合,但加一个我自己总结的修正项——"边际成本拐点"原则:
- 如果一次优化的预期收益 > 该接口 QPS × 单次请求成本 × 年化流量 × 优化幅度 带来的业务价值(哪怕是"少赔一次 SLA 违约"),就值得做。
- 如果优化需要重构(成本 > 1 人周),优先看能否用"小手术"(加索引、改批量、调参数)先止血,把重构排进架构迭代。
- 关键判据不是"降了多少 ms",而是"长尾的方差是否在收敛"。 P99 从 180ms 降到 162ms 但 P999 还在 800ms 晃,说明长尾没治住;P99 从 42ms 降到 41ms 但 P999 从 300ms 降到 55ms,这才是真优化。
一句话:别盯着均值优化,盯着方差收敛。
【想听大家的选择】
抛几个具体问题,想看看不同规模、不同业务形态下的做法差异:
- 你们团队有没有一个明确的"性能优化准入标准"? 比如 P99 超过多少才启动优化?还是纯靠"谁喊疼谁排期"?
- 有没有"优化完发现线上没区别"的案例? 我遇到过两次:profile 显示某方法占 15%,优化后 profile 变了,但 P99 纹丝不动——因为真正的瓶颈在 GC 停顿,而 GC 停顿的根因是堆外内存泄漏,跟那个方法完全无关。
- 架构级优化(比如把同步调用改成事件驱动)怎么向业务方证明 ROI? 我通常用"故障爆炸半径缩小"来论证,但业务方更关心"这个季度能上什么功能"。
- P99 和 P999,你们团队更关注哪个? 我越来越觉得 P999 才是真正反映系统健康度的指标,但很多团队只看 P99,因为"好汇报"。
欢迎带真实案例来聊,最好附上具体的 QPS 量级、P99/P999 数值、优化前后的对比数据。空谈"应该怎样"的帖子我见得够多了,想看看大家手里真实的牌。