性能基准与指标:你总得有个标尺
讲SDK性能调优,最怕什么?不是代码写得烂,是调了半天不知道到底有没有变好。没有指标,一切优化都是玄学。
我个人习惯,接手任何一个SDK项目,第一件事不是改代码,是先拉一张性能基线表。说白了,你得先知道现在跑成什么样,才能谈“优化”两个字。
这一章,我们就来聊聊怎么定义KPI、怎么测量吞吐量、怎么拆解延迟、怎么盯住CPU/内存/IO这三头“吞金兽”,以及最重要的——怎么把基线钉死。
关键性能指标:别什么都想测
什么叫KPI?就是那些你拍桌子说“这个不能降”的指标。不是所有数据都值得画成监控图,我见过很多团队,测了一堆指标,最后开会一张大表,谁都不知道看哪一行。
对于SDK来说,核心KPI通常就四个方向:
- 吞吐量(Throughput)——单位时间能处理多少请求
- 延迟(Latency)——单次请求从进到出要多久
- 资源开销(CPU/Memory/IO)——你跑了多少,吃了多少
- 成功率/错误率(Success Rate)——别光顾着快,跑错了等于白跑
我给团队定的铁律:每个SDK版本发布前,这四项指标必须做一次全量基线采集。少一项,不准发版。
吞吐量:到底能扛多少并发
吞吐量,说白了就是单位时间里能干多少活。常见的单位有:
- QPS(Queries Per Second):每秒查询数,常用于读取密集型SDK
- TPS(Transactions Per Second):每秒事务数,写入或复杂链路更常用
- RPS(Requests Per Second):每秒请求数,覆盖面最广
有一点要注意——吞吐量不能只看峰值。我在项目中遇到过,某个SDK在单线程测出来QPS能到10万,结果一上多线程,直接崩了。只看最好情况,那是自欺欺人。
经验之谈:测吞吐量最好用阶梯加压。从1个并发开始,慢慢往上加,记下每个并发数的QPS。当QPS不再随并发数增加而增长时,那就是你的极限了。
延迟:用户等得起多久
延迟比吞吐量更敏感。吞吐量低一点,用户可能感觉不到;延迟多100毫秒,用户就划走了。
延迟通常看几个百分位:
| 指标 | 含义 | 典型容忍线 |
|---|---|---|
| P50 | 一半请求比这个快 | 小于100ms |
| P90 | 90%的请求能在这个时间内完成 | 小于200ms |
| P99 | 99%的请求能在这个时间内完成 | 小于500ms |
| P999 | 千分之九十九点九,最慢的那一批 | 小于1000ms |
为什么三个要一起看?我记得有一次调优,P50很好看,只有20ms,但P99飙到2秒。排查后发现,是某个高频路径下的锁竞争,大部分请求运气好没撞上,少数倒霉蛋全堵在锁上。只看平均值,永远发现不了这种问题。
避坑指南:千万不要只看平均延迟。平均值会掩盖长尾。我建议把P99当作你的核心延迟指标来盯。
CPU / 内存 / IO:SDK的三条腿
吞吐量和延迟是“结果指标”,CPU、内存、IO是“过程指标”。结果不好,你得从过程里找原因。
CPU开销:别只看CPU占用率,要看是怎么被耗掉的。用户态高说明业务代码重,内核态高说明系统调用多。我曾经优化一个网络库,用户态CPU只有5%,内核态飙到40%,一看代码,每次发消息都单独调一次send(),合并后降到8%。
内存开销:SDK最怕内存泄漏,但更怕的是“峰值内存”。一个SDK平时只吃50MB,突然一个操作蹦到500MB,后果就是整机OOM。我习惯在代码里做内存快照对比,每次接口调用前后各打一次驻留内存。
IO开销:包括磁盘IO和网络IO。对于SDK来说,网络IO尤其重要。每次请求发了多少字节,收了多少字节,这些都是可以直接量化的。我遇到过团队把JSON序列化次数优化掉后,IO量直接降了一半不止。
小技巧:这三个指标要联动着看。CPU高不一定有问题,但CPU高+IO低,说明在空转。内存高+CPU低,说明在等资源。学会读组合信号,比看单一指标有用得多。
如何设定基线:把漂移钉死
基线是什么?就是一把尺子。没有基线,你永远不知道这次改动是变好了还是变差了。
设定基线有几个原则:
- 同一环境——CPU型号、内核版本、JDK版本、网络带宽,必须完全一致。我在项目中遇到过,换了一台宿主机的CPU微架构,基线直接变了20%。
- 同一负载——基线必须在固定负载下采集。我通常用“稳定并发数 + 持续运行5分钟”作为标准。
- 多轮取中位数——跑一轮有随机波动,跑三轮取中位数,比较稳妥。
- 版本号打标——每一个基线必须关联版本号。哪天说“V2.3比V2.2慢了”,能直接查。
下面这张图,是我自己团队一直在用的基线定义流程,你看看就明白了。
一个实战案例:我怎么定基线
说个真事。有一年我做支付SDK,接口调一次要过5个模块。上线前大家觉得“还行”,但因为没有基线,谁都说不上来“还行”具体是多少。
我花了三天做基线:
- 环境锁死:用同一台压测机,4核8G,CentOS 7.9,JDK 8u281
- 负载定在100并发,跑5分钟
- 三轮采集,取P99中位数
结果咧?P99延迟是312ms。团队一群人直呼不可能。后来一个个模块拆,发现一个签名环节用了同步RPC调用,改成异步后,P99降到88ms。如果没有基线,谁有证据说那312ms是不正常的?
核心结论:基线是优化工作的“裁判”。没有裁判,你练再多都是白练。
好,关于KPI、延迟、吞吐量、资源和基线,就聊到这里。记住几个数字:P99盯死、峰值过程指标联动看、基线必须版本打标。这些习惯养成了,后面每一章的方法论才能落地。