来自 技术 2019-03-16 的文章

一篇入门 — Gatling 性能测试手册 - 旻天clock

介绍

本篇博客,旨在记录视频学习的要点,所以格式随意, 方便本人日后自考和回忆,有兴趣的朋友可以评论讨论。原文地址: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.baseimport io.gatling.core.Predef._import io.gatling.http.Predef._import io.gatling.http.config.HttpProtocolBuilderobject 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.baseobject 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.scenarioimport io.gatling.core.Predef._import io.gatling.http.Predef._import io.gatling.core.structure.ChainBuilderimport com.pharbers.gatling.base.phHeaders.headers_baseobject getHome { val getHome: ChainBuilder = exec(http("home") .get("/") .headers(headers_base))}

package com.pharbers.gatling.scenarioimport io.gatling.core.Predef._import io.gatling.http.Predef._import io.gatling.core.structure.ChainBuilderimport com.pharbers.gatling.base.phHeaders.headers_jsonobject 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.simulationimport io.gatling.core.Predef._import scala.concurrent.duration._import com.pharbers.gatling.scenario._import com.pharbers.gatling.base.phHttpProtocolclass 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 SSDJAVA版本1.8.121Scala版本2.11.8Play版本2.5.0-M2Redis版本4.0.1MongoDB版本3.4.4Node.js8.11.2Ember.js2.18.2网络环境公司局域网测试工具Gatling 2.1.7

结果分析测试内容预期结果测试结果备注博客园系统登录页的最大访问量在当前环境下可以1000用户并发,不会造成用户请求失败在3s内逐渐提高并发量,当并发量在643时有三个资源请求失败,在并发量达到689时,有64个资源请求失败未通过,当前博客园系统登录页的最大访问量应小于643博客园系统登录接口的最大并发量在当前环境下可以1000用户并发,不会造成用户请求失败在3s内逐渐提高并发量,当并发量达到1000时,请求资源仍全部成功通过博客园登录页的响应时间在当前环境下用户平均响应时长<2s 95%响应时长<= 5s50th响应时间为1.6s,95th为22s未通过博客园登录接口的响应时间在当前环境下用户平均响应时长<2s 95%响应时长<= 5s50th响应时间 < 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("", "") 判断语句

标签:   云服务业务牌照      证书数量   
上一篇:leetcode题解-122买卖股票的最佳时期 - 守望先生
下一篇:没有了