性能测试===Locust介绍

简述性能测试

提起性能测试,可能移动APP的从业人员会感受比较混淆,由于在客户端(Android、iOS)中也有性能测试专项,主要涉及的是APP的启动时间、内存、包大小、帧率,流量等客户端相关的指标。在本博客以前的文章中,也包含了一些客户端性能测试的内容。须要说明的是,本文所讲解的性能测试都是针对服务器端,尤指Web系统的,与移动APP的性能测试彻底是不一样的领域。python

那么,什么是服务端的性能测试呢?算法

先从你们都熟悉的功能测试提及吧。例如,咱们要测试一个搜索功能,那么咱们测试时,就会输入搜索关键词,点击搜索按钮,而后再去查看搜索结果,看结果是否跟咱们输入的搜索关键词匹配,若是匹配则说明搜索功能实现正确。数据库

Google Search

那如何对该功能进行性能测试呢?编程

答案就是,N我的同时进行功能性操做的同时,在确保功能实现正确的前提下,考察服务端应用程序的各项性能指标,以及服务器硬件资源的使用状况。浏览器

固然,这个答案比较简单粗暴,可是它仍然包含了性能测试的基本特色:缓存

  • 以功能实现正确为前提
  • 一般有必定的并发用户
  • 重点考察服务器端在必定并发压力下的性能指标

最后,再明确下性能测试的目的。一般,对服务器端应用程序开展性能测试,是为了验证软件系统是否可以达到预期的性能指标,同时发现软件系统中存在的性能瓶颈,从而实现优化系统的目的。服务器

性能测试方法的核心

根据不一样的测试目的,性能测试能够分为多种类型,常见的有以下几类:网络

  • 基准测试(Standard Testing)
  • 负载测试(Load Testing)
  • 压力测试(Stress Testing)
  • 疲劳强度测试

首先说下基准测试。基准测试指的是模拟单个用户执行业务场景时,考察系统的性能指标。严格意义上来说,基准测试并不能算做性能测试范畴,它跟功能测试并无太大区别。差别在于,基准测试的目的更多地是关注业务功能的正确性,或者说验证测试脚本的正确性,而后,将基准测试时采集获得的系统性能指标,做为基准测试结果,为后续并发压力测试的性能分析提供参考依据。多线程

负载测试,主要指的是模拟系统在正常负载压力场景下,考察系统的性能指标。这里说的正常负载,主要是指用户对系统能承受的最大业务负载量的指望值,即预计系统最大应该支持多大用户的并发量。经过负载测试,目的是验证系统是否能知足预期的业务压力场景。并发

和负载测试的概念比较接近的是压力测试。通俗地讲,压力测试是为了发如今多大并发压力下系统的性能会变得不可接受,或者出现性能拐点(崩溃)的状况。在加压策略上,压力测试会对被测系统逐步加压,在加压的过程当中考察系统性能指标的走势状况,最终找出系统在出现性能拐点时的并发用户数,也就是系统支持的最大并发用户数。

最后再说下疲劳强度测试。其实疲劳强度测试的加压策略跟负载测试也很接近,都是对系统模拟出系统能承受的最大业务负载量,差别在于,疲劳强度测试更关注系统在长时间运行状况下系统性能指标的变化状况,例如,系统在运行一段时间后,是否会出现事务处理失败、响应时间增加、业务吞吐量下降、CPU/内存资源增加等问题。

经过对比能够发现,不一样的性能测试类型,其本质的差别仍是在加压策略上,而采用何种加压策略,就取决于咱们实际的测试目的,即指望经过性能测试发现什么问题。明白了这一点,性能测试类型的差别也就再也不容易混淆了。

结论要点1:性能测试手段的重点在于加压的方式和策略。

性能瓶颈定位的核心

在前面频繁地提到了性能指标,那性能指标究竟有哪些,咱们在性能测试的过程当中须要重点关注哪些指标项呢?

从维度上划分,性能指标主要分为两大类,分别是业务性能指标和系统资源性能指标。

业务性能指标能够直观地反映被测系统的实际性能情况,经常使用的指标项有:

  • 并发用户数
  • 事务吞吐率(TPS/RPS)
  • 事务平均响应时间
  • 事务成功率

而系统资源性能指标,主要是反映整个系统环境的硬件资源使用状况,经常使用的指标包括:

  • 服务器:CPU利用率、处理器队列长度、内存利用率、内存交换页面数、磁盘IO状态、网卡带宽使用状况等;
  • 数据库:数据库链接数、数据库读写响应时长、数据库读写吞吐量等;
  • 网络:网络吞吐量、网络带宽、网络缓冲池大小;
  • 缓存(Redis):静态资源缓存命中率、动态数据缓存命中率、缓存吞吐量等;
  • 测试设备(压力发生器):CPU利用率、处理器队列长度、内存利用率、内存交换页面数、磁盘IO状态、网卡带宽使用状况等。

对于以上指标的具体含义我就不在此进行逐一说明了,你们能够自行搜索,务必须要搞清楚每一个指标的概念及其意义。可能有些指标在不一样的操做系统中的名称有些差别,可是基本都会有对应的指标,其表明的意义也是相通的。例如,处理器队列长度这个指标,在Windows中的指标名称是System\Processor Queue Length,而在Linux系统中则须要看load averages

可能对于最后一项(测试设备)有些人不大理解,监控被测系统环境的相关硬件资源使用状况不就行了么,为何还要关注测试设备自己呢?这是由于测试设备在模拟高并发请求的过程当中,设备自己也会存在较高的资源消耗,例如CPU、内存、网卡带宽吃满,磁盘IO读写频繁,处理器排队严重等;当出现这类状况后,测试设备自己就会出现瓶颈,没法产生预期的并发压力,从而咱们测试获得的数据也就不具备可参考性了。此处暂不进行展开,后面我会再结合实际案例,经过图表和数据对此详细进行说明。

须要说明的是,性能指标之间一般都是有密切关联的,单纯地看某个指标每每很难定位出性能瓶颈,这须要咱们对各项性能指标的含义了然于胸,而后才能在实际测试的过程当中对系统性能情况综合进行分析,找出整个系统真正的瓶颈。举个简单的例子,压力测试时发现服务器端CPU利用率很是高,那这个能说明什么问题呢?是服务端应用程序的算法问题,仍是服务器硬件资源配置跟不上呢?光看这一个指标并不能定位出产生问题的真正缘由,而若是仅由于这一点,就决定直接去优化程序算法或者升级服务器配置,最后也很难真正地解决问题。

结论要点2:性能瓶颈定位的重点在于性能指标的监控和分析。

引入性能测试工具

经过前面的讲解,咱们已经知道性能测试的主要手段是经过产生模拟真实业务的压力对被测系统进行加压,与此同时监控被测系统的各项性能指标,研究被测系统在不一样压力状况下的表现,找出其潜在的性能瓶颈。

那么,如何对系统进行加压,又如何对系统的指标进行监控呢?这里,就须要引入性能测试工具了。

固然,咱们也能够先看下在不借助性能测试工具的状况下,如何手工地对系统进行性能测试。

假设如今咱们要对前面提到的搜索功能进行负载测试,验证在20个并发用户下搜索功能的事务平均响应时间是否在3秒之内。

很天然地,咱们能够想到测试的必要条件有以下几点:

  • 20个测试人员,产生业务压力
  • 1个指挥人员,对20我的员的协调控制,实现并发操做
  • 1个结果记录人员,对每个人员的操做耗时进行监控和记录
  • 若干资源监控人员,实时查看被测系统的各项性能指标,对指标进行汇总、分析
  • 1个结果统计人员,对20个用户各操做消耗的时长进行汇总,计算其平均值

能够看出,要经过人工来进行性能测试,操做上极为繁琐,须要投入的资源很是多,而这还仅仅是一个很是简单的场景。设想,若是要测试10000并发,服务器有好几十台,显然,这种状况下是彻底不可能经过投入人力就能解决的。这也就是性能测试工具存在的必要性和诞生的背景。

性能测试工具的基本组成

当前,市面上已经有了不少性能测试工具,但无论是哪一款,基本都会包含以下几个核心的模块。

  • 压力生成器(Virtual User Generator)
  • 结果采集器(Result Collector)
  • 负载控制器(Controller)
  • 系统资源监控器(Monitor)
  • 结果分析器(Analysis)

原理结构图以下所示:

Google Search

对照前面手工进行性能测试的案例,不难理解,压力发生器对应的是众多测试人员,结果采集器对应的是结果记录人员,负载控制器对应的是指挥人员,资源监控器对应的是若干资源监控人员,结果分析器对应的是结果统计人员。

其中,压力发生器又是性能测试工具最核心的部分,它主要有两个功能,一是真实模拟用户操做,二是模拟有效并发。

然而,大多数性能测试工做人员可能都会忽略的是,当前市面上性能测试工具的压力发生器基本都是存在缺陷的。

先说下模拟真实用户操做。若是熟悉浏览器的工做原理,就会知道浏览器在加载网页的时候,是同时并发多个TCP链接去请求页面对应的HTTP资源,包括HTML、JS、图片、CSS,当前流行的浏览器广泛会并发6-10个链接。然而,性能测试工具在模拟单个用户操做的时候,基本上都是单链接串行加载页面资源。产生的差别在于,假如页面有100个资源,每一个HTTP请求的响应时间约为100毫秒,那么浏览器采用6个链接并行加载网页时大概会须要1.7秒(100/6*100毫秒),而测试工具采用单链接串行加载就须要10秒(100*100毫秒),二者结果相差十分巨大。这也解释了为何有时候咱们经过性能测试工具测试获得的响应时间挺长,可是手动用浏览器加载网页时感受挺快的缘由。

再说下有效并发。什么叫有效并发?有效并发就是咱们在测试工具中设置了1000虚拟用户数,实际在服务器端就能产生1000并发压力。然而现实状况是,不少时候因为测试设备自身出现了性能瓶颈,压力发生器产生的并发压力远小于设定值,而且一般测试工具也不会将该问题暴露给测试人员;若是测试人员忽略了这个问题,觉得测试获得的结果就是在设定并发压力下的结果,那么最终分析得出的结论也就跟实际状况截然不同了。不过,咱们能够经过保障测试环境不存在瓶颈,使得实际生成的并发压力尽量地与设定值一致;另外一方面,咱们也能够经过在测试过程当中监控Web层(例如Nginx)的链接数和请求数,查看实际达到服务器端的并发数是否跟咱们的设定值一致,以此来反推压力发生器的压力是否有效。

了解这些缺陷的意义在于,咱们能够更清楚测试工具的原理,从而更准确地理解测试结果的真实含义。

性能测试工具推荐

通过充分的理论铺垫,如今总算能够进入正题,开始讲解工具部分了。

在性能测试工具方面,我重点向你们推荐Locust这款开源工具。目前阶段,该款工具在国内的知名度还很低,大多数测试人员可能以前都没有接触过。为了便于理解,我先将Locust与LoadRunner、Jmeter这类大众耳熟能详的性能测试工具进行简单对比。

\ LoadRunner Jmeter Locust
受权方式 商业收费 开源免费 开源免费
开发语言 C/Java Java Python
测试脚本形式 C/Java GUI Python
并发机制 进程/线程 线程 协程
单机并发能力
分布式压力 支持 支持 支持
资源监控 支持 不支持 不支持
报告与分析 完善 简单图表 简单图表
支持二次开发 不支持 支持 支持

经过对比,你们可能会疑惑,Locust也不怎么样嘛,资源监控也不支持,报告分析能力也这么弱,那为啥还要选择它呢?

受权方式这个就不说了。虽然LoadRunner是商业软件,价格极其昂贵,可是国内盗版横行,别说我的,就算是大型互联网公司,用正版的也没几个。

从功能特性的角度来说,LoadRunner是最全面的,用户群体也是最多的,相应的学习资料也最为丰富。我的建议若是是新接触性能测试,能够先熟悉LoadRunner,借此了解性能测试工具各个模块的概念和功能,在此基础上再转到别的测试工具,也都比较好上手了。不过,LoadRunner只能在Windows平台使用,而且并发效率比较低,单台压力机难以产生较高的并发能力,这也是如今我弃用该款工具的主要缘由。

一样地,Jmeter的并发机制也是基于线程,并发效率存在一样的问题;另外,Jmeter在脚本编写和描述方面是基于GUI操做,我的感受操做比较繁琐(这个因人而异),所以不是很喜欢。

那么,我重点推荐的Locust有啥特别的地方呢?

若是从总体功能上来看的话,Locust的功能的确比较单薄。不过,做为性能测试工具最核心的压力发生器部分,倒是很是不错的。抛开官方文档的介绍,我的以为最赞的有两点。

首先是模拟用户操做,也就是测试脚本描述方面。Locust采用Pure Python脚本描述,而且HTTP请求彻底基于Requests库。用过Requests的都知道,这个库很是简洁易用,但功能十分强大,不少其它编程语言的HTTP库都借鉴了它的思想和模式,若是将其评选为最好用的HTTP库之一(不限语言),应该也不会有太大的争议。除了HTTP(S)协议,Locust也能够测试其它任意协议的系统,只须要采用Python调用对应的库进行请求描述便可。

另一点就是并发机制了。Locust的并发机制摒弃了进程和线程,采用协程(gevent)的机制。采用多线程来模拟多用户时,线程数会随着并发数的增长而增长,而线程之间的切换是须要占用资源的,IO的阻塞和线程的sleep会不可避免的致使并发效率降低;正因如此,LoadRunner和Jmeter这类采用进程和线程的测试工具,都很难在单机上模拟出较高的并发压力。而协程和线程的区别在于,协程避免了系统级资源调度,由此大幅提升了性能。正常状况下,单台普通配置的测试机能够生产数千并发压力,这是LoadRunner和Jmeter都没法实现的。

有了一个不错的引擎,外表装饰简陋点也都是能够接受的了。不过虽然Locust功能单薄,特别是在性能指标监控和测试报告图表方面比较缺失,可是Locust的代码结构清晰,核心代码量也只有几百行,可扩展性也很是不错。换言之,Locust的可玩性(hackable)极强,对于一个想深刻挖掘性能测试工具原理的人来讲,Locust很是适合。

好了,Locust的介绍暂且到这儿,后续我会再对Locust的使用方法和二次开发进行详细介绍,也算是弥补官方文档的不足吧。