性能测试
1、介绍
1.1、服务端性能测试的概念
我们要测试一个搜索功能,那么我们测试时,就会输入搜索关键词,点击搜索按钮,然后再去查看搜索结果,看结果是否跟我们输入的搜索关键词匹配,如果匹配则说明搜索功能实现正确。
对于上面的描述我们知道那是基本的功能测试。 那么如何进行性能测试?
答案就是, N个人同时进行功能性操作的同时,在确保功能实现正确的前提下,考察服务端应用程序的各项性能指标,以及服务器硬件资源的使用情况。通过上面的描述我们能总结出性能测试的基本特点:
- 正确实现功能是前提
- 有一定的并发用户
- 重点考察服务端在一定压力下的性能指标
性能测试的目的:
对服务器端应用程序开展性能测试,是为了验证软件系统是否能够达到预期的性能指标,同时发现软件系统中存在的性能瓶颈,从而实现优化系统的目的。
1.2、性能测试的分类
根据不同测试目的,性能测试可以分为多种类型,常见的有如下几类:
基准测试(Standard Testing): 基准测试指的是模拟单个用户执行业务场景时,考察系统的性能指标。严格意义上来讲,基准测试并不能算作性能测试范畴,它跟功能测试并没有太大区别。差异在于, 基准测试的目的更多地是关注业务功能的正确性,或者说验证测试脚本的正确性,然后,将基准测试时采集得到的系统性能指标,作为基准测试结果,为后续并发压力测试的性能分析提供参考依据 。
负载测试(Load Testing): 负载是指模拟业务操作对服务器造成压力的过程,例如,模拟 100 个用户进行登录。在一定软硬件环境下,通过模拟用户负载,来验证系统是否能满足预期的业务压力场景。
压力测试(Stress Testing): 在一定软硬件环境下,通过高负载的手段来是服务器资源处于极限状态(强调服务器资源,硬件资源)。测试系统在极限状态下长时间运行是否稳定
疲劳强度测试: 在一定软硬件环境下,长时间运行一定的负载,确定系统在满足性能指标的前提下是否运行稳定。它和压力/强度区别在于这个负载不强调在极限状态下,着重的是满足性能要求的情况下。但是很多测试人员会持保守观念,在测试极限状态下是否稳定
通过对比可以发现,不同的性能测试类型,其本质的差异还是在加压策略上,而采用何种加压策略,就取决于我们实际的测试目的,即期望通过性能测试发现什么问题。所以, 性能测试手段的重点在于加压的方式和策略
1.3、性能监控指标
性能指标主要分为两大类,分别是 业务性能指标和系统资源性能指标。
1.4、业务性能指标
- 并发数: 单位时间内同时发送给服务器的相同的业务请求数,需限定具体的业务类型.
- 事务吞吐率(TPS/RPS): 单位时间内服务器处理的事务数, 以QPS为单位。该指标值越大越好。一般情况下,用户业务操作过程可能细分为若干个事务,单位时间处理的事务数越多,说明服务器的处理能力越强
- QPS : 全名 Queries Per Second,意思是“每秒查询率”,是一台服务器每秒能够响应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。它代表的是服务器的最大吞吐能力。
- TPS: TPS 即 Transactions Per Second 的缩写,每秒处理的事务数目。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数,最终利用这些信息作出的评估分。
- TPS 的过程包括:客户端请求服务端、服务端内部处理、服务端返回客户端.
- QPS 基本类似于 TPS ,但是不同的是,对于一个页面的一次访问,形成一个 TPS ;但一次页面请求,可能产生多次对服务器的请求,服务器对这些请求,就可计入 QPS 之中。
- 响应时间: 以客户端发出请求,直至接收到服务端的响应数据过程中所消耗的时间作为参考。
- 吞吐量: 单位时间内系统处理用户请求的数量。吞吐量指标直接体现了软件系统的业务处理能力,尤其适用于系统架构选型时做对比测试。
- 吞吐率: 吞吐量/传输时间. 即单位时间内网络上传输的数据量,是衡量网络性能的重要指标。常见的衡量方式:
- 请求数/单位时间
- 点击数/单位时间
- 字节数与/单位时间
- 事务成功率: 定义事务用于度量一个或者多个业务流程的性能指标, 单位时间内可以完成多少个个定义的事务,在一定程度上反应了系统的处理能力.
- 并发用户数: 单位时间内与服务器发生交互的用户数
- 在线用户数: 某段时间内访问系统的用户数, 用户不一定和服务端进行交互
1.5、系统资源性能指标
系统资源性能指标,主要是反映整个系统环境的硬件资源使用情况,常用的指标包括:
- 服务器:CPU利用率、处理器队列长度、内存利用率、内存交换页面数、磁盘IO状态、网卡带宽使用情况等;
- 数据库:数据库连接数、数据库读写响应时长、数据库读写吞吐量等;
- 网络:网络吞吐量、网络带宽、网络缓冲池大小;
- 缓存(Redis):静态资源缓存命中率、动态数据缓存命中率、缓存吞吐量等;
- 测试设备(压力发生器):CPU利用率、处理器队列长度、内存利用率、内存交换页面数、磁盘IO状态、网卡带宽使用情况等。
1.6、性能测试工具
常用的性能测试工具,各有优缺点,如下图:
LoadRunner: 是最全面的,用户群体也是最多的,相应的学习资料也最为丰富。只能在Windows平台使用,并且并发效率比较低,单台压力机难以产生较高的并发能力
Jmeter: java开发跨平台性能测试工具, 基于线程模拟用户数, 单台压力机难以产生较高的并发能力
Locust: 采用纯Python实现,并且HTTP请求完全基于requests库, 采用协程(gevent)的机制,避免系统级别的资源调度,大幅度提高并发数。
性能测试工具的基本组成
压力发生器是最核心的部分 ,它主要有两个功能,一是真实模拟用户操作,二是模拟有效并发。
负载控制器, 主要是分配压力资源
结果采集器, 主要是用来分析对应的结果
资源监控器, 对应测试时系统硬件的各项指标运行情况。
2、Jmeter
2.1、简介
JMeter最初是由Apache软件基金会的Stefano Mazzocchi编写和开发的, 所以Jmeter也称为“Apache JMeter”,它是一个开源的,100%基于Java的应用程序,带有图形界面。
Apache JMeter 是 100%纯 java 桌面应用程序,被设计用来测试客户端/服务器结 构的软件(例如 web 应用程序)。 它可以用来测试包括基于静态和动态资源程序的性能 ,例如静态文件,Java Servlets,Java 对象,数据库,FTP 服务器等等。 JMeter 可以用来在一个服务器、网络或者对象上模拟重负载来测试它的强度或 者分析在不同的负载类型下的全面性能。
另外,JMeter 能够通过 让你们用断言创建测试脚本来验证我们的应用程序是否返回了我们期望的结果 ,从而帮助我们回归测试我们的程序。为了最大的灵活性, JMeter 允许我们使用正则表达式创建断言。
Jmeter的主要功能有:
- web自动化测试
- 接口测试
- 性能测试
- 压力测试
- 通过jdbc进行数据库测试
- java测试
Jmeter的优缺点:
优点:
- 开源工具,可扩展性非常好
- 高可扩展性,用户可自定义调试相关模块代码
- 精心简单的GUI设计,小巧灵活
- 完全的可移植性和100%纯java
- 完全多线程框架,允许通过多个线程并发取样以及单独的线程对不同的功能同时取样
- 支持脚本取样器
缺点:
- 不支持IP欺骗
- 使用JMeter无法验证JS程序,也无法验证页面UI,所以要须要和Selenium配合来完成Web2.0应用的测试
2.2、搭建环境
2.2.1、JDK安装
jmeter 是 java 写的,所以需要 java 的运行环境
2.2.2、Jmeter下载
- Jmeter下载地址:http://jmeter.apache.org/download_jmeter.cgi
下载好之后对压缩文件解压缩
注意:下载后,解压文件到任意目录,避免在一个有空格的路径安装Jmeter,这将导致远程测试出现问题。
2.2.3、启动Jmeter图形化界面方式
windows启动方式:双击安装目录下的
/bin/ApacheJMeter.jar
文件mac or linux启动方式 - 运行安装目录下的
/bin/jmeter.sh
文件提示信息: 不要使用图形换界面进行压力测试,图形化界面只用来创建测试脚本和调试使用 应该使用命令行模式进行压力测试
2.2.4、Jmeter常用目录文件介绍
bin目录存放可执行文件和配置文件
- jmeter.bat:windows系统中JMeter的启动文件
- ApacheJMeter.jar Java环境下的JMeter启动文件
- jmeter.log:日志文件
- jmeter.sh:linux系统中JMeter的启动文件
- jmeter.properties:系统配置文件
- jmeter-server.bat:windows分布式测试要用到的服务器配置
- jmeter-serve:linux分布式测试要用到的服务器配置
2.3、基本使用流程
2.3.1、原件和组件
元件: 相同类似功能组件的集合称之为元件
组件 : Jmeter中的功能点称为组件(元件中子一级的功能即为组件)
主要元件:
- 线程
- 配置: 包含java默认值、http请求默认值、http表头管理器等等
- 定时器(Timer): 包含同步定时器、泊松随时时间等
- 前置(预)处理器: jdbc 预处理器、html链接解析器,用户参数等
- 采样器(Sampler): 包含http请求、jdbc请求、邮件请求等
- 后置处理器: 包含jdbc处理器、xpath抽取器、正则表达式抽取器等
- 断言: 用于检查测试中得到的响应数据是否符合预期.
- 监听器: 包含图表结果、查看结果树、汇总报告等
2.3.2、Jmeter的基本使用流程
需求:
对百度首页请求100次,如何去做?
使用JMeter的解决方案
- 添加【测试计划】
- 基于添加的测试计划添加【线程组】,循环次数设置为100次
- 在【取样器】中基于线程组添加 HTTP请求
- 在【监听器】基于线程组添加[察看结果树]
- 在监听器基于线程组添加[聚合报告]
创建测试计划
- 创建线程组
- 线程数
- pamp-U时间
- 循环次数
添加HTTP取样器
添加察看结果树和聚合报告
运行并查看结果
2.4、相关概念
2.4.1、测试计划
测试计划 是 jmeter 最根一级的结构, 包含执行脚本的所有步骤。测试计划由测试元素组成,包括线程组,逻辑控制器,取样器,监听器,定时器,断言和配置元素等等。
每个测试计划中至少应有一个线程组。
选项:如果测试的时候需要第三方的java 包,可以在这里进行导入。后面我们在测试数据库的时候用到。
2.4.2、线程组
- thread group(线程组): 通常添加使用的线程组,一般一个线程组可以看作一个虚拟用户组,其中每个线程为一个虚拟用户.
- setup thread group: 一种特殊线程组, 可用于执行预测试操作,即执行测试前进行, 一般做初始化操作.
- teardown thread group: 一种特殊的线程组, 可用于执行后操作,即执行测试结束后执行, 一般做结尾操作.
选项:
作用: 添加测试中使用的大多数组件
常用
- 线程数:虚拟用户数,一个线程对应一个虚拟用户
- Ramp-Up Period(in serconds):启动虚拟全部用户数所需要的时间,比如线程数 50,这里设置 10 秒,那么每秒启动 50/10 也就是 5 个线程。如果设置为 0,那么启动后立即开启 50 个线程。
- 循环次数 :指定次数或勾选永远
不常用
- 在取样器错误后要执行的动作
- 继续: 取样器执行时出现错误时,请求不会停止,继续执行
- 启动下一进程循环: 如果出错,那么余下的请求不再执行,直接重新开始执行
- 停止线程: 只限当前线程停止,不影响其他线程执行
- 停止测试: 如果某一线程组的某一请求失败了,则停止所有线程组,也就是停下整个测试,但是每个线程还是会执行完当前的迭代后停止。
- 立即停止测试:所有的线程组全部停止
- 延迟创建线程直到需要: 默认不勾选,测试开始时,所有线程被创建完,若勾选,线程会在需要合适时间进行创建。
- 调度器:勾选后,可以设置下面两个选项
- 持续时间(秒):测试脚本执行多长时间
- 启动延迟(秒):点击运行按钮后,等待多久后开始启动线程进行测试
2.4.3、HTTP请求
作用:
- 模拟前端或第三方软件向服务器发送请求;
- 设置请求时的方法和参数数据;
参数详解:
- 名称:本属性用于标识一个取样器,建议使用一个有意义的名称。
- 服务器名称或IP :HTTP请求发送的目标服务器名称或IP地址。
- 端口号:目标服务器的端口号,默认值为80 。
- 协议:向目标服务器发送HTTP请求时的协议,可以是http或者是https ,默认值为http 。
- 方法:发送HTTP请求的方法,可用方法包括GET、POST、PUT、DELETE。
- 内容编码 :内容的编码方式,默认值为iso8859;一般设置【UTF-8】
- 路径:目标URL路径(不包括服务器地址和端口)
- 同请求一起发送参数: 请求时需要传递参数url 参数
- 消息体数据: 就是请求体内容
- 文件上传: 用户上传文件
Body Data选项作用:
主要是用来发送json 数据, 作为发起请求的参数
2.4.3、查看结果树
作用:
- 查看请求服务器时的请求信息;
- 查看服务器响应数据;
- 记录信息到指定文件;
说明:
- 文件名:将结果保存的一个文件中
- 取样结果:服务器响应的信息头信息;比如:响应代码,响应数据大小
- 请求:查看向服务器请求时的信息;比如:请求地址、方法、数据等
- 响应数据:查看服务器响应的数据;比如:获取资源时,返回的JSON数据
2.4.4、聚合报告
- 平均值、中位数、90%、95%、99%、最小值、最大值 - 这些是指响应的时间,单位毫秒
- 吞吐量 - 每秒钟处理的请求数
- 接收、发送 - 每秒收到和发送字节数的均值 单位是KB
2.4.5、总结
- Jmeter中测试计划是展开测试工作的源头,在测试计划使用中我们根据不同需求创建不同的元件和组件,来实现测试计划。
- 元件是相似功能组件的集合,能够便于管理组件,而组件是某个功能的在Jmeter中的实现.
测试计划中每个 线程组 就是虚拟的 一组用户 ,每个线程就是一个虚拟用户,对于每个用户发起的测试的请求,可以每次定义http请求