一篇入门 — Gatling 性能测试手册
介绍
本篇博客,旨在记录学习的要点,所以格式随意, 方便本人日后自考和回忆,有兴趣的朋友可以评论讨论。
原文地址:https://www.cnblogs.com/clockq/p/10539974.html
一. 性能测试基础
1.1 性能测试时什么?
性能测试时通过自动化的测试工具模拟多种正常、峰值、以及异常负载条件,以此来对系统的各项性能指标进行评测。
性能测试 = 负载测试 + 压力测试
- 通过负载测试,确定在各种工作负载下系统的性能,目的是测试系统的负载逐渐增加的情况下,系统的各项性能指标的变化情况。
- 通过压力测试,确定一个系统的瓶颈或者不能接受的性能点,来获得系统所能提供的最大服务级别。
1.2 性能测试的目的
- 评估系统的能力
- 识别体系中的弱点
- 系统调优
- 检查软件中的问题
- 验证系统稳定性
- 验证系统可靠性
1.3 性能测试的常见观察指标
- Avg Rps: 平均每秒响应次数 = 总请求时间 / 秒数
- Avg time to last byte per terstion(mstes): 平均每秒业务脚本迭代次数
- Successful Rounds: 成功的请求
- Failed Hits: 失败的单击次数
- Hits Per Second: 每秒单击次数
- Successful Hits Per Second: 每秒成功的单击次数
- Failed Hist Per Second: 每秒失败的单击次数
- Attempted Connections: 尝试连接数
- Throughput: 吞吐率
同时,对于服务端的CPU占有率,内存占有率,数据库连接池等也是需要观察的重点。
1.4 性能测试的基本流程
- 明确性能测试需求
- 制定性能测试方案
- 编写性能测试案例
- 执行性能测试案例
- 分析性能测试结果
- 生成性能测试报告
二. Gatling基础 -> 基础使用法
2.1 安装Gatling
获取安装包 http://gatling.io.download/
下载成功后解压即可 使用Gatling需要安装JDK
2.2 使用Gatling
- 编写测试脚本(这块重点学习和讲解)或者使用自带的录制器(bin/recorder.sh)
- 执行测试脚本(bin/gatling.sh),在开启的窗口中选择要执行的脚本
- 查看测试报告(报告默认在“result/”目录下)
- 分析测试结果
三. Gatling 和 Mvn 整合使用 (推荐)
3.1 导入依赖
<properties>
<gatling.version>2.1.7</gatling.version>
<gatling-plugin.version>2.1.7</gatling-plugin.version>
</properties>
<!-- Gatling Module -->
<dependency>
<groupId>io.gatling.highcharts</groupId>
<artifactId>gatling-charts-highcharts</artifactId>
<version>${gatling.version}</version>
</dependency>
3.2 导入插件
<build>
<sourceDirectory>src/test/scala</sourceDirectory>
<testSourceDirectory>src/test/scala</testSourceDirectory>
<plugins>
<!-- Gatling Maven plugin that runs the load-simulation. -->
<plugin>
<groupId>io.gatling</groupId>
<artifactId>gatling-maven-plugin</artifactId>
<version>${gatling-plugin.version}</version>
<configuration>
<configFolder>src/test/resources</configFolder>
<dataFolder>src/test/resources/data</dataFolder>
<resultsFolder>target/gatling/results</resultsFolder>
<runMultipleSimulations>true</runMultipleSimulations>
<simulationsFolder>src/test/scala/com/pharbers/gatling</simulationsFolder>
<simulationClass>com.pharbers.gatling.scenario.getHome</simulationClass>
<!-- <noReports>false</noReports> -->
<!-- <reportsOnly>directoryName</reportsOnly> -->
<!-- <simulationClass>foo.Bar</simulationClass> -->
<!-- <jvmArgs> -->
<!-- <jvmArg>-DmyExtraParam=foo</jvmArg> -->
<!-- </jvmArgs> -->
<!-- <fork>true</fork> -->
<!-- <propagateSystemProperties>true</propagateSystemProperties> -->
<!-- <failOnError>true</failOnError> -->
</configuration>
</plugin>
</plugins>
</build>
3.3 编写脚本
忽略
注意: 脚本要写在 src/test/scala 下
3.4 执行脚本
mvn gatling:execute
3.5 分析报告
四. 现实测试举例
我们先以测试“博客园系统登录页”性能为例,讲解一次测试过程的几个步骤,和测试报告怎么分析。
4.1 明确性能测试需求
好的开始是成功的一半
明确性能测试的需求是至关重要的,所以我们要先有一份测试需求实例
测试需求名称: 博客园登录接口性能测试
| 信息描述 | 描述内容 |
|---|---|
| 参与者 | 张三 |
| 概述 | 测试博客园登录接口的最大并发量 |
| 前置条件 | 博客园前端页面已经成功部署,并可以正常访问 |
| 后置条件 | 无 |
| 业务数据 | 测试登录账号 |
| 不可测试原因 | 网络不可达 |
| 流程规则 | 用户访问博客园登录页,滞留5s,之后调用登录接口 |
| 业务规则 | 无 |
| 页面规则 | 无 |
| 特殊规则 | 无 |
| 接口规则 | 无 |
| 检查内容 | 检查当用户量达到多大时,会导致服务端阻塞,用户响应时间超过5s |
4.2 编写性能测试案例
测试需求名称: 博客园登录接口性能测试
| 测试步骤 | 步骤描述 | 预期结果 |
|---|---|---|
| 步骤 1 | 是否测试博客园登录接口最大并发量 | 确定性能测试登录接口的并发用户数量 |
| 步骤 2 | 启动博客园的前端工程 | 前端工程启动成功 |
| 步骤 3 | 准备性能测试脚本 | 性能测试脚本准备完成 |
| 步骤 4 | 准备测试数据 | 无 |
| 步骤 5 | 执行脚本,验证系统是否满足相关性能测试指标 平均响应时长<2s 95%响应时长<= 5s | 系统满足相关性能测试指标 |
| 步骤 5 | 执行1小时压力测试 | 1. 系统满足相关性能测试指标 2. 1小时压力测试中脚本未报错 |
4.3 执行性能测试案例
按照性能测试案例编写测试脚本
package com.pharbers.gatling.base
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.http.config.HttpProtocolBuilder
object phHttpProtocol {
implicit val noneWhiteList: io.gatling.core.filter.WhiteList = WhiteList()
implicit val noneBlackList: io.gatling.core.filter.BlackList = BlackList()
implicit val staticBlackList: io.gatling.core.filter.BlackList = BlackList(""".*\.js""", """.*\.css""", """.*\.gif""", """.*\.jpeg""", """.*\.jpg""", """.*\.ico""", """.*\.woff""", """.*\.(t|o)tf""", """.*\.png""")
implicit val staticWhiteList: io.gatling.core.filter.WhiteList = WhiteList(""".*\.js""", """.*\.css""", """.*\.gif""", """.*\.jpeg""", """.*\.jpg""", """.*\.ico""", """.*\.woff""", """.*\.(t|o)tf""", """.*\.png""")
def apply(host: String)
(implicit blackLst: io.gatling.core.filter.BlackList, whiteLst: io.gatling.core.filter.WhiteList): HttpProtocolBuilder = { http
.baseURL(host)
.inferHtmlResources(blackLst, whiteLst)
.acceptHeader("application/json, text/javascript, */*; q=0.01")
.acceptEncodingHeader("gzip, deflate")
.acceptLanguageHeader("zh-CN,zh;q=0.9,zh-TW;q=0.8")
.doNotTrackHeader("1")
.userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36")
}
}
package com.pharbers.gatling.base
object phHeaders {
val headers_base = Map(
"Accept" -> "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Upgrade-Insecure-Requests" -> "1")
}
package com.pharbers.gatling.scenario
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.core.structure.ChainBuilder
import com.pharbers.gatling.base.phHeaders.headers_base
object getHome {
val getHome: ChainBuilder = exec(http("home")
.get("/")
.headers(headers_base))
}
package com.pharbers.gatling.scenario
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.core.structure.ChainBuilder
import com.pharbers.gatling.base.phHeaders.headers_json
object userLogin {
val feeder = csv("loginUser.csv").random
println(feeder)
val login: ChainBuilder = exec(http("login")
.get("/api/user/login")
.headers(headers_json)
.body(StringBody("""{ "condition" : { "email" : "nhwa", "password" : "nhwa" } }""")).asJSON)
}
package com.pharbers.gatling.simulation
import io.gatling.core.Predef._
import scala.concurrent.duration._
import com.pharbers.gatling.scenario._
import com.pharbers.gatling.base.phHttpProtocol
class userLogin extends Simulation {
import com.pharbers.gatling.base.phHttpProtocol.{noneBlackList, noneWhiteList}
val httpProtocol = phHttpProtocol("http://192.168.100.141:9000")
val scn = scenario("user_login")
.exec(
getHome.getHome
.pause(5 seconds),
userLogin.login
.pause(60 seconds)
)
setUp(scn.inject(rampUsers(1000) over (3 seconds))).protocols(httpProtocol)
}
并执行上述脚本
4.4 分析性能测试结果
看下图,可以看到67% + 8%的请求可以在1.2s内完全,同时在1000用户的并发测试下,会有用户请求不到资源,也就是加载失败。
其实,这个地方,可以通过修改gatling.conf来改变表格的渲染区间,使结果更符合我们的测试要求

这里,75th的总响应时间=1s,还是很快的,但95th的总响应时间>9s, 所以不符合我们的测试要求。

我们使用递增的方式,在3s内逐渐增加用户并发量,并且用户会滞留5s + 60s,在下图中就得到了体现

下图是本次测试,在每个时间点的请求情况,包含请求状态(成功,失败)和请求数量

还有更多图表,就不一一展示了,我们主要就是查看前两个图表,以此判断服务器所能承受的压力。
当然,如果需要考查更多标准,就需要查看其它图表,比如延迟分布图,负载分布图等等。。。。
4.5 生成性能测试报告
一份合格的性能测试报告,至少应该包含如下内容:
- 测试基本信息: 包含: 测试目的,报告目标读者,术语定义,参考资料
- 测试环境描述: 包含: 服务器软硬件环境,网络环境,测试工具,测试人员
- 性能测试案例执行分析: 需要详细描述每个测试案例的执行情况,以及对对应测试结果进行分析
- 测试结果综合分析及建议:对本次性能测试做综合分析,并给出测试结论和改进建议
- 测试经验总结
博客园登录接口性能测试报告
测试信息
信息描述 描述内容 测试人员 齐钟昱 测试目的 检查当用户量达到多大时,会导致服务端阻塞,用户响应时间超过5s 术语定义 50th,安装递增排序后,排在50%的请求的信息 术语定义 95th,安装递增排序后,排在95%的请求的信息 参考资料 零成本实现Web性能测试[电子工业出版社] 测试环境
信息描述 描述内容 服务器系统 CentOS Linux release 7.4.1708 (Core) 服务器集群数量 4 服务器内存(台) 16G 服务器CPU核心数(台) 12 服务器硬盘空间(台) 256G SSD JAVA版本 1.8.121 Scala版本 2.11.8 Play版本 2.5.0-M2 Redis版本 4.0.1 MongoDB版本 3.4.4 Node.js 8.11.2 Ember.js 2.18.2 网络环境 公司局域网 测试工具 Gatling 2.1.7 结果分析
测试内容 预期结果 测试结果 备注 博客园系统登录页的最大访问量 在当前环境下可以1000用户并发,不会造成用户请求失败 在3s内逐渐提高并发量,当并发量在643时有三个资源请求失败,在并发量达到689时,有64个资源请求失败 未通过,当前博客园系统登录页的最大访问量应小于643 博客园系统登录接口的最大并发量 在当前环境下可以1000用户并发,不会造成用户请求失败 在3s内逐渐提高并发量,当并发量达到1000时,请求资源仍全部成功 通过 博客园登录页的响应时间 在当前环境下用户平均响应时长<2s 95%响应时长<= 5s 50th响应时间为1.6s,95th为22s 未通过 博客园登录接口的响应时间 在当前环境下用户平均响应时长<2s 95%响应时长<= 5s 50th响应时间 < 1s,95th < 1s 通过 测试总结
根据上述分析报告,本次性能测试为通过制定要求,博客园系统登录功能的最大并发量应小于643,为保持性能,建议并发数小于500
五. 常用脚本api
5.1 并发量控制
atOnceUsers(100)使用100并发量测试目标服务器rampUsers(100) over (10 seconds)循序渐进的增大压力,在10s中内线性增加用户数达到最大压力100并发量nothingFor(10 seconds)等待10sconstantUsersPerSec(rate) during(duration)在指定duration内,以固定频率注入用户,每秒注入rate个用户,默认固定间隔constantUsersPerSec(rate) during(duration) randomized与上面不同的是用户以随机间隔注入rampUsersPerSec(rate1) to (rate2) during(duration)在指定duration内,以递增频率注入用户,每秒注入 rate1 ~ rate2 个用户
5.2 用户行为控制
.exec()实际的用户行为.pause(20)用户滞留20s,模拟用户思考或者浏览内容.pause(min: Duration, max: Duration)用户随机滞留,滞留时间在min ~ max 之间
5.3 流程控制
repeat(time, counterName)内置循环器foreach(seq, elem, counterName)foreach循环器csv("file").random创建填充器doIf("", "")判断语句
一篇入门 — Gatling 性能测试手册的更多相关文章
- Tp5安全篇入门
输入安全 设置public目录为唯一对外访问目录,不能把资源文件放入到应用目录: 使用框架提供的请求变量获取方法(Request类的param方法及input助手函数)而不是原生系统变量获取用户输入的 ...
- 测者的性能测试手册:JVM的监控利器
测者的性能测试手册:JVM的监控利器 每次聊起性能测试,最后的终结话题就是怎么做优化.其实在Java的复杂项目中都会有内存不足问题.内存泄露问题.线程死锁问题.CPU问题.这些问题工程测试或者是小压力 ...
- 第一篇 入门必备 (Android学习笔记)
第一篇 入门必备 第1章 初识Android 第2章 搭建你的开发环境 第3章 创建第一个程序--HelloWorld 第4章 使用Android工具 ●Android之父 Android安迪·罗 ...
- 一篇入门Express
目录 1.安装 2.Hello World 3.基础路由设置 4.高级路由设置 5.静态文件 6.中间件 7.生成器 1.安装 Express 是一个 基于 Node.js 的简洁灵活的 Web 应用 ...
- 学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳
学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 9 / 25 转载请注明出处!️ 目录 学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳 ...
- 学会Git玩转GitHub(第二篇) 入门详解 - 精简归纳
学会Git玩转GitHub(第二篇) 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 10 / 25 转载请注明出处!️ 目录 学会Git玩转GitHub(第二篇) 入门详解 - 精简归纳 ...
- 学会Git玩转GitHub(第三篇) 入门详解 - 精简归纳
学会Git玩转GitHub(第三篇) 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 10 / 25 转载请注明出处!️ 目录 学会Git玩转GitHub(第三篇) 入门详解 - 精简归纳 ...
- jenkins:应用篇(Gatling plugin的使用)
Jenkins的功能强大,在于它的插件式框架,能扩展功能,自动化当中,很容易想到的是对提交的新代码做测试,这里gatling主要是负责压力测试,也就是所谓的性能.关于gatling,可以参考我前面的博 ...
- 一篇入门 -- Scala
整体介绍 Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性. 联邦理工学院洛桑(EPFL)的Martin Odersky于2001 ...
随机推荐
- linux下查看动态链接库so文件的依赖的相关组建
我们很多c程序在windows下是以dll形式展现的,在linux则是以so 形式展现的. windows一般不会因为编译dll文件的编译器版本不同而出先dll文件不能执行. 但是linux下,不同版 ...
- Java多线程消费者、生产者的基本思路
多线程主要考察的就是 线程的同步控制 生产者消费者的思路就是,当 一个线程执行时让另一个线程 挂起就行了 ThreadOne.ThreadTwo同时运行,添加一个变量在一个公共类(下边的Funct ...
- C#多线程--信号量(Semaphore)[z]
百度百科:Semaphore,是负责协调各个线程, 以保证它们能够正确.合理的使用公共资源.也是操作系统中用于控制进程同步互斥的量. Semaphore常用的方法有两个WaitOne()和Releas ...
- java、php、.net关于web开发的区别
一提到web开发,目前在世界上流行性的三个帮派就是php,java和asp.net,这个世界上的百分之99的网站或者类似的应用都是由这三种语言的开发,这里请原谅我忽视某些小众语言如python之类.三 ...
- hbase-bloom filter
bloom fliter的作用主要用于提升hbase的读性能,但是会牺牲一定的存储空间. 原理: bloom fliter是一种空间效率很高的随机数据结构,初始状态时,bloom filter是一个包 ...
- python中的深浅copy
https://www.cnblogs.com/Eva-J/p/5534037.html 转自Eva_J 分析的特别好
- 201621123002《java程序设计》第十三周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 为了让你的系统可以被多个用户通过网 ...
- 201621123002《Java程序设计》第十周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1. 常用异常 结合题集题目7-1回答 1.1 自己以前编写的代码中经常出现 ...
- POJ 3140.Contestants Division 基础树形dp
Contestants Division Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10704 Accepted: ...
- NC 刷新后,停留上一次选择的行(多行)
如图,我点击批量输入后,会调用列表刷新按钮.但数据之前选择的光标会跳到第一行,原先选择的行就不知道是哪行可.图为最终效果 // 批量输入日期后实时刷新 apply update(batch input ...