前言:

最近业务高速迭代发展,需要考虑系统的稳定性,降低线上系统问题导致的业务风险,此时需要评估、确定系统的瓶颈,未雨绸缪,提前准备应对措施。这里主要介绍上如何做一场压力测试。

目标:

一定要搞清楚压力测试的目标,知道了目标,才知道压力测试的意义与成果。
其实我理解的目标:
1. 评估系统性能瓶颈,看系统瓶颈在哪里,是DB、磁盘、网络?
2. 确定目前的系统能否支持预估的业务量,举个例子,比如业务线要开支持新城市,那么根据推算,新开城市之后,业务的高峰的流量能达到多少,比如5W qps,压力测试可以选择高于这个峰值的流量比如 6W qps 进行压测,看上下游系统是否满足要求。

一般来讲,对于孵化期的业务,通常会是第二种情况下去做压力测试。

流程

1.压测前准备:
压测环境:为各个服务准备一套与线上环境极其近似的环境,机器配置、数据库、缓存等,这里 不再多说。
压测数据:这个最好从线上一台机器进行流量的录制,常见的工具有tcpdump tcpcopy,也有一些巨头有自己的平台去做这些事情,比如阿里的doom,美团的quake等。数据库数据也可以从线上dump一份,如果量大的话,也可以不考虑。
业务链路:主要是根据业务场景目标,梳理出一套自己系统的调用全链路。比如压测的目标接口、调用的上下游服务。
压测场景:主要是根据业务目标,详细拆分出自身的压测场景,以电商服务为例,比如首页压测场景,关注于首页的各个接口和服务,还有下单场景、履约场景、等等根据业务目标实时灵活变动。
压测工具: 这个不在一一介绍,简单的有ab,jmeter,loadrunner等等。
2. 开始压测:
开始压测,一般来讲,我们会逐步动态调整压测的流量,比如从1w qps ,稳定之后(比如运转30分钟正常,时间可以调整),再逐步加压,便于发现系统一旦崩溃,知道瓶颈是在哪个流量阶段,这里主要是关注系统的各个状况。
一般来讲,业务系统需要观测各个接口及上下游的响应时间及系统的一些监控情况,比如GC、load,磁盘利用率等等。
3.压测结束
对于目标1的情况,发现系统瓶颈,无论是代码、db、缓存、网络、磁盘等,找到对应策略,进行修复就可以了。
对于目标2的情况,压测、改进,直到达到目标即可。

系统优化

这里简单介绍一些常见的优化思路。

1.性能指标:
我们一般关注的业务系统的性能指标有三个:
Throughout 吞吐量 ,通俗说就是系统的QPS
Latency 延迟 ,也就是响应时间
Usage 资源利用率。

2.定位性能问题:
底层系统层面
磁盘IO、Load、网络等等
业务系统层面
JVM :
GC/FullGC次数、GCTime, 堆内存、永久区(元数据区)使用情况等等。
java thread情况、是否有热锁等。
必要时需要dump内存 和 线程堆栈。
业务系统:
接口耗时、QPS

3.性能优化思路
业务:
1. 缩短调用链路,从而减少调用时间,每多一次网络调用,都有不少耗时,还有网络抖动的风险。
2. 精简业务对象,比如接口建立防腐层,减少传输对象的大小,内存中的对象减小,优化对内存占用,提高GC效率。
3. 优化业务逻辑,这个方向比较大,需要从业务层面对代码进行抽象,优化,减少无意义的计算。
基础技术:
1. 代码+数据结构:
这里主要是针对代码的设计,比如优化代码中的算法,循环次数,正则表达式的效率,代码的抽象设计,都是要考虑的。
2. 空间换时间/时间换空间:
这个是老生长谈的问题了,空间换时间,比如大家经常用到的缓存,缓存数据是经过很多逻辑计算出来的,或者是反向索引。
时间换空间,典型的网络请求,网络带宽成瓶颈的时候,需要对接口传输的对象进行压缩,接收方再进行解压缩。
3. 批量、并发、异步
批量,这里举个反例,一般出现再新工程师写的代码,在for循环中进行RPC调用,这种就需要批量接口减少无用的网络耗时。
并发,这个是相对于同步说的,比如A 服务调用下游B、C、D…服务,如果 同步调用,则耗时为 B + C + D…,并行调用的话则 max{B、C、D}。
异步,这个跟并发有些类似,有些地方并没有详细的区分,这里举个例子就是常用的回调的服务。

总结

本文笔者简述了在业务高速增长期的压力测试过程,性能优化方案,其实还有架构层面、DB、缓存等方面的优化这里笔者没有提到,后续大家也需要关注。