系统正式上线之前,通常要做性能压测,好处就多了:
- 了解系统能正常处理多少用户请求
- 尽早发现性能瓶颈并做优化
- 调整部署资源分配
- 设置合理的监控指标
开始压测之前
压测目标
首先是设定目标。这次压测的目标,是找到系统能够支持的并发用户数、核心链路的tps、资源的峰值消耗(cpu、内存、缓存等)、还是某个接口的响应瓶颈?
压测方案
为了实现目标,哪些服务需要被压测,它们之间的依赖关系是怎样的,涉及哪些中间件,服务的交互流程,压测流程的设计,执行时间,执行次数,需要重点关注的指标,有哪些数据要反映在压测报表,等等。
一般对于一个新的app,至少要覆盖用户使用的核心路径,即用户打开app->使用核心功能->用户离开。
环境准备
除非有特殊原因,不能随便使用线上环境进行压测,否则后患无穷。 一般要有配套的环境专门性能压测。硬件规格、软件配置要和线上一致。现在是容器化时代,镜像解决了很多软件配置的问题了。实例部署数量可以适当缩小。
指标
“我的系统可以支撑100W用户并发”,这是没有多大工程意义的。系统所能够支撑的用户数,还要看并发请求的成功率、TP99或者TP90的响应时间,才有意义。
提高系统并发的方式很多:增大tcp的backlog、增大tomcat的acceptor线程、增大业务的线程池数量……用户请求是建立了,但是由于系统不能及时处理,导致请求响应时间10s+、大量请求等待超时、请求失败等。显然,这样并发数对系统是没有意义的。
相对于并发数,吞吐量(throughput)指标考虑单位时间的处理能力。
吞吐量 = 处理请求数 / 时间
10W个请求,总共处理10s,那么吞吐量是1W/s。但是,吞吐量不要求所有请求都是同一时间触发。因此,吞吐量1W/s不等于支撑1W并发请求。另外,吞吐量只反映单位时间处理的请求数,并没有反映单个请求的响应时间。
响应时间(response time,RT)值得多说。10W个并发请求过来,由于一开始系统资源充裕,前面的请求处理很快,100ms返回了;随着请求数量变多,平均RT变成1s,有的一直等待资源的请求RT要5s。 一个常见的问题是,使用平均响应时间作为性能指标。在统计学上,平均数是很不靠谱的,容易受极端值影响,同时也容易掩盖极端值。而在生活中,被平均的坑爹感觉没少经历过。 更为合理的是,使用区间响应时间来描述性能,即TP99 100ms、TP90 20ms、TP50 5ms等。 TP(top percentile),即区间的百分之X的请求都落在这个值以内。
最后,成功率是一个容易被忽略的指标,总是默认总是成功。但是在微服务时代,服务可以降级,因此要根据业务的意义,确定服务链路发生降级是否也算成功。
综合起来,合理描述性能的指标,可以是:
TP99小于10ms、最大RT 100ms,系统最大支持并发请求1W。
工具
jmeter,ab,python,monkey,blabla。
实施压测
压测预热
一个常见的问题是,系统还没预热,就做性能压测。为什么要预热?tcp连接建立、缓存不命中回源加载、jvm热代码编译(分层编译)等都会对性能产生明显的影响,导致系统性能变低。 对于没有预热的系统施加高并发压测,得到的冷启动+突发流量下系统的性能,而不是平稳状态下的性能。
怎么做压测预热呢?先以低的并发度逐渐增加,比如100、200、500,压测1min、2min、5min,等RT稳定后再逐渐增加到期望值并发值,每次增加500到1000,压测1min。
单压 vs 混压
另一个常见的问题是,只对单个接口、单个服务调用的场景做压测(单压),没有根据用户使用场景同时对多个接口、服务做压测(混压)。 单压可以方便发现单个接口、服务的问题。但是单压不能很好的反映真实场景下多个接口、服务的资源竞争导致的性能问题。 比如一个服务有a、b、c三个接口,都是使用redis,单压每个接口都能轻松TP99 5ms + 3W 并发。但是如果同时对这个3个接口做压测,可能就只剩下TP99 5ms + 1W 并发了,因为底层竞争使用redis资源。 多接口、多服务的混压,可以帮助发现此类性能问题,对衡量系统的真实并发有积极意义。
观察指标
cpu load,内存,网络接口流量,磁盘读写次数,存储空间使用,jvm gc次数等,使用top,vmstat, tsar,jstat等工具。 中间件控制台。缓存命中率、缓存空间使用、metaq消息堆积情况、数据库并发事务数等。 RT的曲线图,TP99时间。 服务调用的耗时分布。
压测问题排查
记得首先记录问题复现路径,并且保留现场。
报告
- 单压、混压
- TP99、TP90响应时间
- 并发数
- 关键资源的消耗
- 压测方式
- 瓶颈分析
- 结论
使用压测报告
除了修复性能问题,压测报告在调整部署资源上也很有用。 资源申请在项目启动阶段就开始做,否则来不及准备软硬件设施。那时候的资源规划大概率是拍脑袋出来的。压测报告给了修正机会,更好的预估系统的资源需求,在上线之前做好资源调整。
另外再举个例子,一个cpu密集型的服务,60% cpu使用率,支持1W并发;90% cpu使用率,支持1.5W并发。在做资源规划的时候,应该使用60%-80%使用率作为参考,参考价值比较高。90%的使用率,系统已经高负荷的边缘,不能很好应对突发情况,不适合长期稳定运行。用90%使用率下的并发数去做资源规划就危险了。
此外就是设置告警指标。比如一个接口期望TP90小于100ms,就可以做个监控项。