相关代码下载:VipCoinSimulation.tar.gz
Gatling是一款基于Scala 开发的高性能服务器性能测试工具,它主要用于对服务器进行负载等测试,并分析和测量服务器的各种性能指标。目前仅支持http协议,可以用来测试web应用程序和RESTful服务等。
Gatling的特点是:
支持Akka Actors 和 Async IO,从而能达到很高的性能;
录制并生成测试脚本,测试脚本简单,对开发人员友好;
实时动态生成html报表;
开源免费。
目前web应用程序和中间层相关接口都可以使用此工具进行测试,主要介绍下接口是如何测试的。
下载及安装
gatling官方网址是:http://gatling.io/。
下载地址:http://gatling.io/download/。其中2.x和1.x版本有很大的不同,2.x版本是重新开发的,包括很多的语法都不一样。查看文档时也需要保持与版本号一致。
gatling需要JDK7u6以上的java环境。
下载完成后,解压即可。
编写测试脚本
a. 关于web应用程序测试及脚本录制等方法,可以参考http://gatling.io/docs/2.0.0-RC2/quickstart.html。有非常细致的说明。
b.接口测试
gatling测试脚本使用了scala语言。但是脚本都非常简单易懂,不需要对scala有太深入的了解。
创建测试脚本VipCoinSimulation.scala,放在$GATLING_HOME/user-files/simulations/computerdatabase下。computerdatabase 这个文件夹是可以自定义的,与包名相一致。
VipCoinSimulation继承了Simulation,所有的测试脚本都应该继承这个。
然后我们可以准备具体的接口测试了。
首先,先设置http请求的相关参数,如url,header等。
1 2 3 4 5 |
val httpConf = http.baseURL("http://dingjing.coinapi.youku.com") .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") .doNotTrackHeader("1") .acceptEncodingHeader("gzip, deflate") .userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0”) |
baseURL就是请求地址。val关键字代表的是常量,一经定义无法更改,变量声明可以用var。
下面,就需要构造具体的请求参数了。已get_account_by_id接口为例,get_account_by_id需要两个参数uid和platform。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
object get_account_by_id { val feeder = csv("get_account_by_id.csv").random def getSign(uid: String, platform: String, pub_key: String, sign_type: String, secretKey: String) = { Sign.createSign(Map("uid" -> uid, "platform" -> platform, "pub_key" -> pub_key, "sign_type" -> sign_type), secretKey) } val request = feed(feeder).exec(http("get_account_by_id") // let's give proper names, as they are displayed in the reports .get("/vipcoins/get_account_by_id") .queryParam("""uid""", "${uid}") .queryParam("""platform""", "{platform}") .queryParam("""pub_key""", """L001""") .queryParam("""sign_type""", """MD5""") .queryParam("""sign""", session => { getSign(session("uid").as[String], session("platform").as[String], "L001", "MD5", secretKey) }) .check(regex("coins").exists)) } |
一步步来解释。在scala中,如果要定义单例对象,使用object关键字。
在模拟一个用户的请求的时候,uid和platform是固定,如果要模拟多个呢?数据是随机动态的呢?就需要feeder的定义了。
get_account_by_id.csv 的内容如下:
uid,platform
123,1
111,1
10000000,9
10000005,9
10000008,9
10000009,9
10000010,9
10000011,9
当具体发起请求的时候,数据会从csv文件中随机选择。csv文件中用逗号作为分隔符,这分隔符也可以自定义。get_account_by_id.csv 放在$GATLING_HOME/user-files/data下。
函数定义使用def。getSign定义了如何获取sign签名。
feed(feeder)加载csv文件数据。exec执行具体的请求。http(“get_account_by_id”)设置了请求名称,可以在显示到报表中。queryParam可以添加请求参数,是get请求参数。
需要注意下sign值的设置。
1 2 3 |
.queryParam("""sign""", session => { getSign(session("uid").as[String], session("platform").as[String], "L001", "MD5", secretKey) }) |
我们直接在getSign中获取”${uid}”是不行的。可以通过session方式。session保存了整个请求的消息。
exec执行完成后,可以通过check操作来测试请求是否成功。get_account_by_id 请求成功返回的是json数据,如果正常的话,是有coins信息的。所以用了regex(“coins”).exists 来检查。当然,可以设置多条件检查,比如http的返回码等。
上面模拟了一个用户的请求行为。接下来需要设置整个测试的行为。
1 |
val getAccountById = scenario("GetAccountById").exec(get_account_by_id.request) |
scenario就是设置的单个用户的请求行为。
1 |
setUp(getAccountById .inject(atOnceUsers(1)).protocols(httpConf)) |
意思是一个用户发起请求。
如果设置并发的用户的话,可以设置
1 |
constantUsersPerSec(50) during(60 seconds) |
意思是在60秒内,每秒有50个用户进行请求。
3. 执行测试
*nix系统:
在$GATLING_HOME下。执行sh bin/gatling.sh,出现
选择1之后,一直按回车,默认即可。
如果要查看请求的Log信息,修改$GATLING_HOME/conf/logback.xml, 打开
<logger name=”io.gatling.http” level=”TRACE” /> 注释就可以。
windows系统,只要双击同名文件的bat文件就可以。
4. 查看测试结果:
执行完成后,会有个简单的测试报告。在上面我们可以看到请求数量,执行时间分布,成功数等。除此之外,还会生成html格式的报表,通过本地或者web服务都可以直接访问。
5. 总结
除了良好的性能测试外,gatling还可以充当自动化测试工具的角色。可以批量的测试接口及web服务。
6.参考
新一代服务器性能测试工具Gatling :http://www.infoq.com/cn/articles/new-generation-server-testing-tool-gatling
官方文档:http://gatling.io/docs/2.0.0-RC2/
setUp(scn.inject(ramp(3 users) over (10 seconds)))
setUp(scn.inject( constantUsersPerSec(10) during(5 seconds)))—–报错
官方文档说明:
constantUsersPerSec
Injects users at a constant rate, defined in users per second, during a given duration
(nbUsers) during(dur unit)
Injects nbUsers each second for duration. Eg : constantUsersPerSec(10) during(5 seconds)
这一方面的用法有疑问,有没有练习方式请指教。
.queryParam(“””sign”””, session => {
getSign(session(“uid”).as[String], session(“platform”).as[String], “L001”, “MD5”, secretKey)
})
为什么直接${}取不到值,我在实际中session也提示没有这个值
当具体发起请求的时候,数据会从csv文件中随机选择。csv文件中用逗号作为分隔符,这分隔符也可以自定义。——-在哪里自定义呢
gatling目前不支持分布式,也就是说,只能自己本机去发起压力,有没有办法让gatling能够多台机器同时对服务器施加压力,本机只是座位一个master,统计结果用,压力发起方,给angent机器?