Appearance
基准测试 Cheatsheet
第一个案例
sh
# 4 线程;100 并发;持续 30 秒
=> wrk -t4 -c100 -d30s --latency -s post.lua https://bridge.aliyun.com/abs/home/queryUserBaseInfo
Running 30s test @ https://bridge.aliyun.com/abs/home/queryUserBaseInfo
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 106.41ms 13.33ms 310.58ms 78.46%
Req/Sec 232.17 35.95 290.00 89.38%
Latency Distribution
50% 104.80ms
75% 111.63ms
90% 120.00ms
99% 161.16ms
27597 requests in 30.07s, 28.45MB read
Requests/sec: 917.77
Transfer/sec: 0.95MB指标:
- QPS(Requests/sec) 每秒处理请求数 吞吐量
- 时延 P99 P95 尾部高延迟 长尾性能
- 标准差 Stdev 距离感知器 越小越好;
+/- Stdev落入“平均 ± 标准差”的请求比例 越大越好 - 并发连接数
目标:低延迟,高吞吐
诊断定位篇:性能瓶颈常见源头
| 层级 | 典型问题 |
|---|---|
| 网络层 | DNS 慢、连接复用失败 |
| 应用层 | GC 停顿、锁竞争、慢查询 |
| 数据库 | 索引失效、连接池不足 |
| 缓存 | Redis 执行时间长、key miss |
| 系统资源 | CPU 打满 / 磁盘 IO 阻塞 |
| 容器资源 | Pod CPU/内存限制、OOM Kill |
调优方向篇:压出问题,怎么改?
| 问题 | 常见优化手段 |
|---|---|
| 延迟高 | 减少链路 hop,优化 SQL,异步化 |
| QPS 上不去 | 加连接池、加 worker、扩容服务 |
| 超时多 | 优化 tail latency,减重资源依赖 |
| 错误多 | 捕获异常、幂等重试、降级保护 |
| 内存飙升 | 优化 GC、检查缓存 / 对象泄漏 |
| CPU 高 | 找热点函数、分析 CPU profile |
性能分级
| 档位 | 等级 | P99 时延 | QPS 范围 | 说明 |
|---|---|---|---|---|
| 🟢 入门档 | 初创项目 | ≤ 500ms | ≤ 500 | 不要超秒,能用 |
| 🟡 合格档 | 商业级 | ≤ 200ms | ≤ 5,000 | 正常体验 |
| 🟠 稳定档 | 核心系统 | ≤ 100ms | ≤ 20,000 | 满足大部分 C 端系统 |
| 🔴 高性能档 | 高并发系统 | ≤ 50ms | ≥ 50,000 | 适配字节、美团、淘宝级 |
| 🟣 极速档 | 内核/推荐系统 | ≤ 10ms | ≥ 100,000 | 对标推荐/搜索系统内部链路 |
系统接口性能目标速查表
| 接口类型 | 场景示例 | 目标 QPS | 平均时延 | P99 时延 | 错误率容忍 | 备注 / 告警建议 |
|---|---|---|---|---|---|---|
| 🧍 用户关键路径接口 | 首页加载、点击、评论、点赞 | 500 ~ 5,000 | < 100ms | < 300ms | < 0.5% | 一旦 > 500ms,用户体验下滑,建议 P99 > 500ms 告警 |
| 🔐 登录/下单/支付类 | 登录注册、支付确认、订单提交 | 100 ~ 3,000 | < 80ms | < 200ms | < 0.1% | 丢单风险,强 SLA,P95 超过 200ms 建议报警 |
| 🧠 后台管理接口 | 数据列表、表单查询等 | 10 ~ 500 | < 300ms | < 800ms | < 1% | 容忍度高,但也别太离谱,建议 P99 超过 1s 告警 |
| 🔄 异步服务 / 任务调度 | 报表生成、批量导出、数据清洗 | 100 ~ 5,000 | < 800ms | < 2s | < 1% | 时延长但要稳定,建议时延跳变报警 |
| 🔌 微服务内部 RPC | 服务间接口调用(用户中心 -> 订单) | 1,000 ~ 50,000 | < 30ms | < 100ms | < 0.01% | 延迟越低越好,建议延迟波动/错误率同步告警 |
| 📡 数据查询类接口(高频) | 搜索接口、联想词推荐 | 5,000 ~ 50,000 | < 50ms | < 100ms | < 0.1% | Latency 为首要指标,超过 100ms 就容易卡顿 |
| 🧪 开放平台 API | 开放 SDK、三方系统接入 | 1,000 ~ 10,000 | < 150ms | < 500ms | < 0.5% | 公网访问时延略高,注意请求峰值压测 |
| 🤖AI/模型接口 | Chat 接口、识别类 | 100 ~ 1,000 | 300ms ~ 2s | 2s+ | < 1% | 推理时间主导,但需做响应控制 |
P99 长尾性能的指标
P99 延迟 = 所有请求中 99% 的请求耗时小于这个值,只有最慢的 1% 会更慢。
简单说,P99 代表“最慢但还算可接受的体验下限”。你可以把它看成“长尾性能”的一个重要分位指标。
什么是 P99
P99 是你系统在“最差时刻”的表现底线。它比平均值、中位数更真实地揭示了你服务的“长尾痛点”。
如果你想要打造高质量、高体验的接口服务,P99 是你最该盯死的一个性能指标之一,就像防线一样,守不住底线,就可能挂掉用户信任。
怎么看 P99 高不高?
参考我刚刚给你的性能目标:Web 用户接口 P99 最好 < 300ms,你这 161ms 是 ✅ 可接受的范围内
如果这是高频、核心接口,目标再压到 120ms 以内更理想
如何优化 P99?
一、应用层
1、避免慢查询
- ❌ select * from user where email like '%abc%'
- ✅ 建好索引,写精确条件,limit 控制返回量
🧠 举个例子:
你后端接口查用户信息,结果忘记加 where id = ?,全表扫,你的 P99 就直接炸成烟花。
2、缓存兜底(靠近热点)
- ✅ Redis 做用户数据缓存,查用户不查 DB
- ✅ 不变数据放本地内存(比如城市列表、枚举)
🧠 举个例子:
有 1% 用户查的是“冷门数据”,如果每次都直连 DB 查询,P99 就拖下来了。冷数据用异步预热缓存搞定!
3、避免同步调用链过长
- ❌ A → B → C → D → E(每一层都等)
- ✅ 尽量压平调用链,拆成并行/异步
🧠 比如查询用户信息时,还同步去查订单、积分、最近登录行为……这等于是把别人的慢也背在自己身上。
4、接口限流 + 降级策略
- ✅ 拦掉大流量下的非核心请求
- ✅ 后台查询失败时直接返回缓存 or 提示稍后再试
🧠 举个例子:
你接口平时快,一旦突发流量,DB 抽风,P99 直接冲上 3 秒。如果你能识别“非 VIP”请求直接降级返回默认数据,P99 就能拉回来。
二、系统层
1、线程池调优 / goroutine 限制
- ✅ 不要把线程/协程开得太满,爆了反而雪崩
🧠 举个例子:
你开了 500 个 goroutine 处理请求,但数据库连接池就 50 个,结果 450 个 goroutine 都在等资源,P99 崩盘。
2、连接池设置合理(DB、Redis、HTTP)
- ✅ 比如 PG 用
pgx设置合理 max_conn - ✅ HTTP client 连接复用、keepalive 调整
3、Nginx / Ingress / Envoy 等网关级优化
- ✅ 设置合理 timeout
- ✅ 开启 gzip 压缩
- ✅ 限流和缓存策略
三、监控与压测配合
1、工具推荐:
- 🔍 APM(全链路追踪):比如 Jaeger、Skywalking、Zipkin
- 📈 Prometheus + Grafana:监控指标,观察 P99 波动
- 🔧 wrk / hey / k6:精准压测找出瓶颈
四、总结:P99 优化五步法
| 阶段 | 行动 | 说明 |
|---|---|---|
| 1 | 采样监控 | 收集 P99 指标,标记异常时段 |
| 2 | 链路追踪 | 找出哪些操作最慢 |
| 3 | 局部优化 | 改慢 SQL、加缓存、调线程 |
| 4 | 全链路压测 | 用 wrk/k6 模拟真实场景验证 |
| 5 | 设防线限流 | 加限流、降级避免尾部炸锅 |