原文见:在路上的博客
服务端性能测试系列下一篇:工具篇 (Jmeter),从性能测试常用功能角度,熟悉 Jemter。
从 14 年 11 月到 18 年 6 月,一直专注于服务端性能测试,发现有些同学经常对一些基础概念和指标有异议,故写本文,希望对大家认识性能测试有一定帮助。也欢迎大家多多指正。
因性能测试知识跟自己的从业经历强相关,但性能知识范围甚广,不同的业务、不同的技术架构,我们的关注点和指标要求可能会区别较大,欢迎大家指正文中不足或错误之处,并附上相关资料链接,方便大家传阅。
全文包括:
- 什么是性能
- 性能对用户和产品收入影响
- 性能测试目的、性能关注指标、性能测试类型、性能测试流程
- 常用的性能测试工具对比
随着 5G 时代的到来,以及万物互联时代的到来,云应用和云服务会越来越多,数据量会指数级增长。尤其是 2020 年全球疫情的时代意义,会导致各行各业开始上云。从而会催生出极具个性化的各类产品的诞生。
所有行业的生态会像鲸落效应一样,围绕若干个巨无霸公司衍生出满足人们各种需求的中小型产品。大部分产品的形态可能会变成重服务端、轻客户端。
所以,服务端性能测试的需求也有可能会出现井喷式增长。但是服务端性能测试需求对于中小型公司,尤其是大部分不关注用户体验的公司来说,性能测试需求特点是周期短、时间紧。
因此,对于大部分测试从业人员来说,了解并掌握常见的性能测试知识是必不可少的,虽然不会经常用到。
不同角色关注的性能是不一样的,性能测试这项系统工程,需要各角色在其关注的纬度提供信息或帮助。
性能对于用户来说,就是操作的响应速度、产品的崩溃是否影响自己的生活。比如滴滴之前在情人节当天打车服务的性能事故。

老板主要关心产品的收入、成本(用了多少钱服务了多少用户)、用户满意度(用户对产品是否满意)。




对于大部分商业公司的 ToC 产品,性能关乎产品命运和增长。如下图所示,虽然现在阿里京东垄断不太容易更换应用,但是遇到性能很差的时候,心里还是忍不住问候几句。

大家都知道性能对产品收入有非常大的影响,但是很少公司有全面的运营分析来证明这件事。
以下是《2016 全球零售业数字化性能基准报告》中关于性能对收入影响的数据。
从图中可以看到,响应时间对转化率的影响非常大,比如沃尔玛够硬核了吧,沃尔玛的响应时间降低 0.1 秒,收入即可增加 1%,是非常大的收入提升。

以中小型电商网站为例,如下图所示,性能基本组成:
- 客户端 (Web、移动端、小程序) 性能
- DNS 性能
- 负载均衡服务性能
- Nginx 集群性能、折损率
- CDN 缓存性能(回源率、穿透率)
- 应用服务器性能
- DB 性能(Mysql/Redis/Memcache)
由此可见,中大型项目的性能测试,从来都是一项系统工程,需要非常多人跨部门合作,且持续时间长,耗费资源大。

熟悉性能测试之前,首先了解性能测试的目标是什么。带着目标去思考会更有利于理解下面的内容。
性能测试的最终目的是为了最大限度的满足用户的需求,通常要达成以下目标:
(1)性能评估:测试中评估系统的 QPS、响应时间、成功率等;
(2)寻找系统瓶颈,进行系统调优;
(3)检测软件中的问题;
(4)验证稳定性和可靠性;
一般来说,性能测试要统一考虑这么几个因素:Thoughput 吞吐量,Latency 响应时间,资源利用(CPU/MEM/IO/Bandwidth…),成功率,系统稳定性。
(1)响应时间:你得定义一个系统的响应时间 latency,建议是 TP95 或以上。响应时间具体要求多少,一般读不超过 200ms,写不超过 500ms。要是实在不知道,对标同行业竞品。
(2)最高吞吐量:TPS(每秒事务请求数)或 QPS(每秒请求量),在目标响应时间要求下,系统可支撑的最高吞吐量。
(3)成功率:在关注 QPS 和响应时间的同时,还要关注成功率。如果 QPS 和响应时间都满足性能要求时,请求成功率只有 50%,用户也是不会接受的。
(4)性能拐点:一般服务都有性能临界点。当超过临界点时,吞吐量非线性下降,响应时间指数级增加,成功率降低。
找到出现性能拐点的主要原因:
基于性能拐点主要原因设置高危性能报警线。此为高风险注意事项,因为一旦达到性能拐点,有可能会出现雪崩现象,造成极其严重的事故。
观察超过性能拐点后,系统是否会出现假死、崩溃等高风险事件。
(5)系统稳定性:保持最高吞吐量(目标响应时间下的最高吞吐量),持续运行 7*24 小时。然后收集 CPU,内存,硬盘/网络 IO,等指标,查看系统是否稳定,比如,CPU 是平稳的,内存使用也是平稳的。那么,这个值就是系统的性能。
(6)极限吞吐量:阶梯式增加并发压力,找到系统的极限值。比如:在成功率 100% 的情况下(不考虑响应时间的长短),系统能坚持 10 分钟的吞吐量。
(7)系统健壮性:做 Burst Test。用第二步得到的吞吐量执行 5 分钟,然后在第四步得到的极限值执行 1 分钟,再回到第二步的吞吐量执行 5 钟,再到第四步的权限值执行 1 分钟,如此往复个一段时间,比如 2 天。收集系统数据:CPU、内存、硬盘/网络 IO 等,观察他们的曲线,以及相应的响应时间,确保系统是稳定的。
(8)低吞吐量和网络小包的测试:有时候,在低吞吐量的时候,可能会导致 latency 上升,比如 TCP_NODELAY 的参数没有开启会导致 latency 上升(详见 TCP 的那些事),而网络小包会导致带宽用不满也会导致性能上不去,所以,性能测试还需要根据实际情况有选择的测试一下这两咱场景。
首先简单分析性能测试的压力模型。
如下图所示,随着单位时间压力的不断增长,被测系统和服务器的压力不断增加,TPS 会因为这些因素而发生变化,而且通常符合一下规律。


为得到性能关注的指标,基本分为以下性能测试类型:
- 性能测试(狭义)
- 说明:性能测试方法是通过模拟生产运行的业务压力量和使用场景组合,测试系统的性能是否满足生产性能要求。通俗地说,这种方法就是要在特定的运行条件下验证系统的能力状态。
- 特点: 1、这种方法的主要目的是验证系统是否有系统宣称具有的能力。 2、这种方法要事先了解被测试系统经典场景,并具有确定的性能目标。 3、这种方法要求在已经确定的环境下运行。 也就是说,这种方法是对系统性能已经有了解的前提,并对需求有明确的目标,并在已经确定的环境下进行的。
- 负载测试 (Load Test)
- 说明:通过在被测系统上不断加压,直到性能指标达到极限(例如 “响应时间”)超过预定指标或都某种资源已经达到饱和状态。
- 特点: 1、这种性能测试方法的主要目的是找到系统处理能力的极限。 2、这种性能测试方法需要在给定的测试环境下进行,通常也需要考虑被测试系统的业务压力量和典型场景、使得测试结果具有业务上的意义。 3、这种性能测试方法一般用来了解系统的性能容量,或是配合性能调优来使用。 也就是说,这种方法是对一个系统持续不段的加压,看你在什么时候已经超出 “我的要求” 或系统崩溃。
- 压力测试(强度测试)(Stress Test)
- 说明:压力测试方法测试系统在一定饱和状态下,例如 cpu、内存在饱和使用情况下,系统能够处理的会话能力,以及系统是否会出现错误
- 特点: 1、这种性能测试方法的主要目的是检查系统处于压力性能下时应用的表现。 2、这种性能测试一般通过模拟负载等方法,使得系统的资源使用达到较高的水平。 3、这种性能测试方法一般用于测试系统的稳定性。 也就是说,这种测试是让系统处在很大强度的压力之下,看系统是否稳定,哪里会出问题。
- 并发测试(Concurrency Testing)
- 说明:并发测试方法通过模拟用户并发访问,测试多用户并发访问同一个应用、同一个模块或者数据记录时是否存在死锁或其者他性能问题。
- 特点: 1、这种性能测试方法的主要目的是发现系统中可能隐藏的并发访问时的问题。 2、这种性能测试方法主要关注系统可能存在的并发问题,例如系统中的内存泄漏、线程锁和资源争用方面的问题。 3、这种性能测试方法可以在开发的各个阶段使用需要相关的测试工具的配合和支持。 也就是说,这种测试关注点是多个用户同时(并发)对一个模块或操作进行加压。
- 配置测试(Configuration Testing)
- 说明:配置测试方法通过对被测系统的软硬件环境的调整,了解各种不同对系统的性能影响的程度,从而找到系统各项资源的最优分配原则。
- 特点: 1、这种性能测试方法的主要目的是了解各种不同因素对系统性能影响的程度,从而判断出最值得进行的调优操作。 2、这种性能测试方法一般在对系统性能状况有初步了解后进行。 3、这种性能测试方法一般用于性能调优和规划能力。 也就是说,这种测试关注点是 “微调”,通过对软硬件的不段调整,找出这他们的最佳状态,使系统达到一个最强的状态。
- 可靠性测试
- 说明:通过给系统加载一定业务压力(例如资源在 70%-90% 的使用率),使系统运行一段时间,以此检测系统是否稳定运行。
- 特点: 1、这种性能测试方法的主要目的是验证是否支持长期稳定的运行。 2、这种性能测试方法需要在压力下持续一段时间的运行。(2~3 天)3、测试过程中需要关注系统的运行状况。 如果测试过程中发现,随着时间的推移,响应时间有明显的变化,或是系统资源使用率有明显波动,都可能是系统不稳定的征兆。 也就是说,这种测试的关注点是 “稳定”,不需要给系统太大的压力,只要系统能够长期处于一个稳定的状态。
- 失效恢复测试
- 说明:如果系统局部发生故障,用户是否能够继续使用系统,以及如果这种情况发生,用户将受到多大程度的影响。
- 特点: 1.这种性能测试方法的主要目的是验证在局部故障情况下,系统能否继续使用。 2.这种性能测试方法还需要指出,当问题发生时,“能支持多少用户访问” 的结论和 “采取何种应急措施” 的方案。 3.一般来说,只有对系统持续运行指标有明确要求的系统才需要进行这种类型的测试。
- 大数据量测试:针对某些系统存储、传输、统计查询等业务进行大数据量的测试。
注意:在做性能测试时请忘掉分类。例如,运行 8 个小时来测试系统是否可靠,而这个测试极有可能包含了可靠性能测、强度测试、并发测试、负载测试,等等。因此,在实施性能测试时决不能割裂它们的内部联系去进行,而应该基于测试目标,分析它们之间的关系,以一种高效率的方式来设计性能测试。

性能需求分析是整个性能测试工作开展的基础,如果连性能的需求都没弄清楚,后面的性能测试工具以及执行就无从谈起了。
在这一阶段,性能测试人员需要与 PM、DEV 及项目相关的人员进行沟通,同时收集各种项目资料,对系统进行分析,确认测试的目标。并将其转化为可衡量的具体性能指标。
测试需求分析阶段的主要任务是分析被测系统及其性能需求,建立性能测试数据模型,分析性能需求,确定合理性能目标,并进行评审;
主要包括:设计场景,根据场景编写程序、编写脚本、准备测试环境,构造测试数据,环境预调优等;
设计场景:针对系统的特点设计出合理的测试场景。为了让测试结果更加准确,这里需要很细致的工作。如建立用户模型,只有知道真实的用户是如何对系统产生压力,才可以设计出有代表性的压力测试场景。这就涉及到很多信息,如用户群的分布、各类型用户用到的功能、用户的使用习惯、工作时间段、系统各模块压力分布等等。只有从多方面不断的积累这种数据,才会让压力场景更有意义。最后将设计场景转换成具体的用例。
测试数据:测试数据的设计也是一个重点且容易出问题的地方。生成测试数据量达到未来预期数量只是最基础的一步,更需要考虑的是数据的分布是否合理,需要仔细的确认程序中使用到的各种查询条件,这些重点列的数值要尽可能的模拟真实的数据分布, 否则测试的结果可能是无效的。测试数据最好使用线上脱敏后的数据,尽可能接近真实用户行为。
预调优:指根据系统的特点和团队的经验,提前对系统的各个方面做一些优化调整,避免测试执行过程中的无谓返工。比如一个高并发的系统,10000 人在线,连接池和线程池的配置还用默认的,显然是会测出问题的。
执行阶段工作主要包含两个方面的内容:一是执行测试用例模型,包括执行脚本和场景;其次测试过程监控,包括测试结果、记录性能指标和性能计数器的值
至于性能问题的分析、定位或者调优,很大程度是一种技术问题,需要多方面的专业知识。数据库、操作系统、网络、开发都是一个合格的性能测试人员需要拥有的技能,只有这样,才能从多角度全方位的去考虑分析问题。
基于目前市场上主流的性能工具,进行横向对比测试,以帮助我们在不同的环境灵活选择不同的测试工具。
测试对象:Nginx index.html(612Byte),CPU:16 核 / 内存:16GB / 磁盘:500GB
压力机:Ubuntu18.04, CPU: 8 核 / 内存:8G / 磁盘: 500GB

在此只进行了最基础的性能对比测试,仅供基本的工具选择判断。
阿里京东也在用,天生为分布式开发的,易用性很好
优势:
轻量级性能测试工具;
安装简单(相对 Apache ab 来说);
学习曲线基本为零,几分钟就能学会咋用了;
基于系统自带的高性能 I/O 机制,如 epoll, kqueue, 利用异步的事件驱动框架,通过很少的线程就可以压出很大的并发量;
劣势:
基础使用:
子命令参数说明:
PS: 关于线程数,并不是设置的越大,压测效果越好,线程设置过大,反而会导致线程切换过于频繁,效果降低,一般来说,推荐设置成压测机器 CPU 核心数的 2 倍到 4 倍就行了。
报告解析:
Jmeter 是 Java 开发的、基于多线程并发模型的压测工具,也是目前最流行的开源压测工具,工作原理类似,如下图:

- 其所谓的虚拟用户 (vuser) 就是对应一个线程
- 在单个线程中,每个请求(query)都是同步调用的,下一个请求要等待前一个请求完成才能进行
- 一个请求(query)分成三部分:
- send - 施压端发送开始,直到承压端接收完成
- wait - 承压端接收完成开始,直至业务处理结束
- recv - 承压端返回数据,直至施压端接收完成
- 同一线程中连续的两个请求之间存在等待时间这种概念,即图中的空白处
在多线程并发模型下,是不是可以通过不断增加线程数量生产出更大的压力?
答案是否定的。
事实上一个进程在一个时间点只能执行一个线程,而所谓的并发是指在进程里不断切换线程实现了看上去的多个任务的并发,但是线程上下文切换有很高的成本,过多的线程数反而会造成性能的严重下滑。

从应用角度来看,基于多线程的并发模型,往往需要设置最大并发数参数,而如果压测场景需要不断往上加压,那这类工具其实挺难应付的。
Locust 是用 Python 开发的分布式压测工具,近年来在国内比较流行。Locust 并不是基于 Python 的多线程,而是 coroutine(协程,gevent 提供),gevent 使用了 libev 或者 libuv 作为 eventloop。
Locust 响应时间失真问题:
Locust 当压力机 CPU 达到瓶颈后,响应时间会严重失真。
比如当 Locust normal 模式下,8 进程,CPU 瓶颈后,90% 响应时间为 340ms。同时 wrk 获取的响应时间为 59.41ms.


基本使用介绍:
装饰器 task 可以设置压力比例
- HttpUser 示例:
- FastHttpUser 示例
- 启动及分布式
2 线程: -c1000 -t1(因最少 2 线程)QPS: 35560.79
wrk -c1000 -t1 -d30s --latency http://10.60.82.91/

3 线程:( -c1000 -t2 QPS: 66941.77 )
wrk -c1000 -t2 -d30s --latency http://10.60.82.91/

8 线程: ( -c1000 -t8 QPS: 75579.30 )
wrk -c1000 -t8 -d30s --latency http://10.60.82.91/
Nginx: 86% * 16 = 1376% , 达到 CPU 瓶颈

Wrk: CPU = 40% * 8 = 320%

1 进程:(10 并发,QPS:512)

Nginx:(CPU:8.6%)

Locust:(CPU:100%, 单核 CPU 达到瓶颈)

8 进程:(100 并发,QPS:3300)

Nginx: (CPU:50%)

locust:(CPU:800%, CPU 达到瓶颈)

1 进程:(10 并发,QPS:1836, 90%RT: 5ms)

Nginx:(CPU:24%)

Locust:(CPU:100%, 单核 CPU 达到瓶颈)

8 进程:(100 并发,QPS:11000, 90%RT: 7ms)

Nginx:(CPU:150%)

locust:(CPU:800%, CPU 达到瓶颈)

8 核 (100 并发,QPS:38500)

Nginx:(CPU:397.3%)

Jmeter:(CPU:681%)

- 性能测试之并发模型对比 (Jmeter/Locust/Gatling)
- 左耳朵耗子 - 性能测试应该怎么做?
- Dynatrace-2016 全球零售业数字化性能基准报告
- 支付宝性能测试实战 [剑风]
- 网银在线性能测试指南(京东金融)
- 聊聊 ab、wrk、JMeter、Locust 这些压测工具的并发模型差别
- 性能工具 wrk 介绍
- Locust 官方文档
- mac 安装 locust 问题:解决 MacOS 升级后出现 xcrun: error: invalid active developer path, missing xcrun 的问题
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/9100.html