事前准备
要做好一个压测,首先要了解下面的一些背景知识,才能做好压测计划。
了解你的压测目标:有多少流量?大概的分布是怎样的?需要压测的 QPS 是多少?
了解业务系统:各个业务场景对应的接口是什么?接口背后有些什么依赖(数据库、缓存、OSS)?
压测数据准备:是否需要准备不同的请求数据?写操作如何处理脏数据?读操作注意响应大小对性能的影响?
后端依赖摸底:是否需要 mock 掉一部分后端依赖?mock 对评估的准确性有多大影响?
例如根据业务评估和系统场景的细分,最终确定了压测的目标:
按照 10w DAU 用户量预估,PV = 15 * DAU = 1500000,平均分布在 8 小时内,总 QPS = 52。
移动端的编辑场景不多,主要是阅读场景:
场景
接口
占比
预估 QPS
目标 QPS
首页
/api/v2/users/:userId/groups
25%
13
39
我的文档
/api/v2/user/docs
10%
5
15
最近编辑
/api/v2/user/recent-updated
10%
5
15
团队页面
/api/v2/groups/${this.data.groupId}
/api/v2/groups/${this.data.groupId}/repos
10%
5
15
知识库页面
/api/v2/repos/${this.data.repoId}
/api/v2/repos/${this.data.repoId}/docs
/api/mobile/repos/${this.data.repoId}/toc
5%
3
7.5
文档详情
/api/mobile/docs/:id
/api/mobile/comments
40%
21
63
以上面的这个比例来对接口进行混合压测。
目标页面 QPS = 156,目标接口 QPS = 250
压测性能标准
为了保证压测得到的数据下,用户体验不受影响,要保证压测过程中满足下列的性能条件,否则压测得到的数据可能是虚高的。
指标 |
要求 |
备注 |
CPU |
<= 70% |
|
响应时间 |
<= 100ms |
特殊接口特殊分析 |
峰值错误率 |
<= 1% |
尽量做到无错误 |
load1 值 |
< CPU 核数 - 0.5 |
例如 4 核 ECS,则 load1 最大为3.5 |
内存 |
<= 80% |
尽量不能随压力变大而增加内存消耗 |
压测环境和工具
可以编写 lua 脚本来定制请求的参数,例如我们可以通过下面的脚本来实现同时按照不同的比例对不同的接口进行混合压测
压测过程中我们要观察什么?
系统指标
根据性能压测标准中指定的需要观察的内容,需要监控系统的一系列指标,包括 CPU,load,内存,响应时间等等,我们可以通过下面的手段来查看这些指标:
压测平台:如果是内部系统压测,使用压测平台可以查看到实时的 QPS、响应事件等信息
xflush:查看集群或者单机的 CPU / 内存 / Load 等性能指标,PV / 数据库访问量 / 远程服务调用量等业务指标
tsar:在每台机器上执行 tsar 可以查看到实时的 CPU / Load / Traffic 等指标
日志:通过日志可以找到一些慢请求或者实现一些特殊场景的监控
在观测过程中,还需要注意机器的负载是否均衡,每一台机器上各个 CPU 是否负载均衡。可以观测各个进程的 CPU 或者通过日志来判断。
CPU Profile
为了发现真实场景下的性能瓶颈,建议在压测的过程中使用 alinode 生成一份 CPU Profile,从中寻找性能瓶颈进行优化,建议挑选达到最高 QPS 时,在长时间的稳压过程中来生成 CPU Profile。
一般来说,现在 node 使用的 v8 版本已经对各种 js 的写法都已经优化的很不错了,很难通过改变 js 层面的写法提升性能,最有效的优化手段是下面这几种:
通过空间换时间,如果可以的话,通过增加缓存的方式来避免热点代码的多次执行。
优化热点代码的算法复杂度。
优化业务逻辑,避免执行热点代码。
其他依赖
根据“事前准备”中我们了解到的业务技术架构,需要进一步观察对应的其他依赖服务和系统的指标:
如果请求数据库,观察数据库的 CPU / 内存占用,是否有慢查询?
如果请求缓存,观察缓存的命中率,准备的测试数据是否足够分散和真实环境的命中率相差不大?CPU 和内存占用率如何?
如果请求后端系统,观察后端系统的水位,同时避免影响到后端系统对外提供服务。