压力测试工具tsung初体验

简介

最近参与开发了公司的评论和点赞的系统,该系统是作为symfony的一个独立plugin,可能会被其它很多系统使用,比如说图片,视频,newsfeed等等,都有可能直接嵌入,所以该独立模块做的尽可能通用,对性能也有一定要求。最终采用以mysql作为储存方案,以redis作为缓存方案的设计。接口开发完后想对接口进行性能负载测试,估算该系统的读写性能的上限。

了解了几个常用的测试工具和与公司之前所用的测试工具进行对比后,最终选定tsung进行测试工具:

tsung是erlang开发的一个开源的多协议分布式负载测试工具,它能用来压力测试HTTP, WebDAV, SOAP, PostgreSQL, MySQL, LDAP 和 Jabber/XMPP的服务器。它可以分布在多个客户机,并能轻松够模拟成千上万的虚拟用户数并发。

安装

首先是安装tsung,因为最新的tsung是1.6.0版的,系统自带的源可能没有最新版本,所以到官网http://tsung.erlang-projects.org/ 下载源码包来编译,configure && make && make install完成。

配置文件

tsung是根据xml配置文件里的参数内容来进行压测。默认tsung会加载配置文件:~/.tsung/tsung.xml

如果该文件夹下初始为空,则在/usr/share/doc/tsung/examples下有样例的xml文件,http的配置是http_simple.xml

下面来讲几个关键的配置

clients

用户产生的方式

1
2
3
<clients>
<client host="localhost" use_controller_vm="true" maxusers="30000"/>
</clients>

tsung运行时可以由很多的虚拟机组成,client配置指明这个client机器上最多生成的用户数,如果use_controller_vm为true的话,那么当用户数达到mmaxusers,tsung会自动生成新的VM。

servers
1
2
3
<servers>
<server host="test.com" port="80" type="tcp"></server>
</servers>

server段可以配置被测服务器的相关信息,也可以配置成集群,如下

1
2
3
4
<servers>
<server host="server1" port="80" type="tcp" weight="4"></server>
<server host="server2" port="80" type="tcp" weight="1"></server>
</servers>

这时tsung会根据weight值来选择发起请求的server

monitoring

系统监控服务,配置完后可获取被测server的cpu,内存,负载,数据库的相关信息。可以配置成erlang的监控服务和snmp的监控服务。

1
2
3
4
5
<monitoring>
<monitor host="garden" type="erlang">
<mysqladmin port="3306" username="root" />
</monitor>
</monitoring>
load
1
2
3
4
5
<load>
<arrivalphase phase="1" duration="3" unit="minute">
<users maxnumber="100" interarrival="0.02" unit="second" ></users>
</arrivalphase>
</load>

load段可配置访问的负载,访问可以配成多个阶段,由phase值指定。duration是测试持续时间,unit是单位。

users段的maxnumber限制了生成的最大用户数,interarrival=”0.02”表示0.02秒产生一个新用户,用户按照session的配置顺序执行session中的request。

options
1
2
3
4
5
6
<options>
<option type="ts_http" name="user_agent">
<user_agent probability="80">Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.8) Gecko/20050513 Galeon/1.3.21</user_agent>
<user_agent probability="20">Mozilla/5.0 (Windows; U; Windows NT 5.2; fr-FR; rv:1.7.8) Gecko/20050511 Firefox/1.0.4</user_agent>
</option>
</options>

options段可配置一些请求的信息,如agent信息。

sessions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<sessions>
<session name="http-example" probability="70" type="ts_http">
<setdynvars sourcetype="random_number" start="1" end ="100">
<var name="itemid" />
</setdynvars>
<transaction name='getlist'>
<request subst="true">
<http url="/comment/getList" method="POST" contents = "item_type=image&amp;item_id=%%_itemid%%"></http>
</request>
</transaction>
</session>
<session name="http-example" probability="30" type="ts_http">
<setdynvars sourcetype="random_number" start="1" end="100">
<var name="itemid" />
</setdynvars>
<setdynvars sourcetype="random_number" start="20" end="5000000">
<var name="content" />
</setdynvars>
<transaction name='getlist'>
<request subst="true">
<http url="/comment/addComment" method="POST" contents = "item_type=image&amp;item_id=%%_itemid%%&amp;content=%%_content%%"></http>
</request>
</transaction>
</session>
</sessions>

可配置多个子session,进而可测试多个api,可以设置请求概率,在probability里被定义,要求每个session的probability之和是100。类型是http。

sessions里可用for来设定请求次数,如下

1
<for from="1" to="@loop" incr="1" var="counter">

里面可以设置请求的具体信息。在请求参数里可以带上随机数。随机数和随机字符串的定义如下:

1
2
3
4
5
6
<setdynvars sourcetype="random_number" start="20" end="5000000">
<var name="xxx" />
</setdynvars>
<setdynvars sourcetype="random_string" length="10">
<var name="xxx" />
</setdynvars>

以%%_xxx%%的形式来调用,这里必须注意的是,要使用随机数,request必须加上subst=”true”参数,不然随机数无法被引用成功。随机数也可从文件读取,如csv。

http内部可定义header参数:

1
2
3
4
<http_header name="Authorization" value="111"/>
<http_header name="Cookie" value="authToken=%%_auth_token%%; Path=/"/>
<!-- content-Type:POST请求参数的格式,如果是json格式可以这样写 -->
<http_header name="Content-Type" value="application/json"/>

thinktime可用于定义两个请求的间隔时间

1
<thinktime value="1"/>

另外可定义不同的transaction ,这样子结果里就会显示不同transaction的具体信息。

开始测试

运行命令

1
tsung start

开始测试

运行时执行

1
tsung status

可获取tsung运行时的状态

生成报表

测试程序结束后,进入log文件夹下的对应结果文件夹,执行

1
tsung_stats

就可以得到我们想要的结果报表了。

分析结果报表

生成好后的report.html就是测试的最终结果。

Main statistics里有一些总体的信息
Main statistics
有几张重要的结果图如下:

  • tsung产生的用户曲线图
    graphes users simulaneous
    Y轴代表每秒用户数,tsung每秒会产生一批用户,这个统计结果是每十秒统计一次,所有的图的起始位置显示的是0,其实是第一个10秒
  • http接口响应数曲线图(TPS)
    http code
    Y轴是每秒响应数,右上角的200是http状态码,如果有多个状态码,会有多条不同颜色的曲线。
  • http接口响应时间曲线
    mean request
    Y轴是接口响应时间,单位是毫秒,request的线代表请求响应总耗时,connect的线代表tcp链接建立的时间。

后记

经过测试,发现该系统支持的最大写入频率是80次/min,因为并未加入cache, queue等优化方案,是直接同步写库,初始业务量也未必会很大,所以该数据也已满足正式环境的使用。根据测试结果我们改进了一些逻辑SQL,使执行效率尽可能高。

另外还使用了innotop作为mysql的监控工具,htop作为系统负载的监控工具,在这里就不展开介绍了:)