环境搭建ok后我们开始使用tsung进行性能测试
其实tsung提供了一系列的模板,包括所有tsung支持的服务类型的xml模板
cd /usr/local/tsung/share/doc/tsung/examples/
1. 客户端
<clients>
<client host="localhost" cpu="4" maxusers="30000"/>
</clients>
tsung-1.0.dtd源码文件中对客户端参数的定义 tsung-1.0.dtd
<!ELEMENT clients (client+)>
<!ELEMENT client (ip*| iprange) >
<!ATTLIST client
cpu NMTOKEN "1"
type (machine | batch) "machine"
host NMTOKEN #IMPLIED
batch (torque | pbs | lsf | oar) #IMPLIED
scan_intf NMTOKEN #IMPLIED
maxusers NMTOKEN "800"
use_controller_vm (true | false) "false"
weight NMTOKEN "1">
2. 服务端
<servers>
<server host="tsung-dev.test.lluozh.com" port="80" type="tcp" />
</servers>
tsung-1.0.dtd源码文件中对服务参数的定义 tsung-1.0.dtd
<!ATTLIST server
host NMTOKEN #REQUIRED
port NMTOKEN #REQUIRED
weight NMTOKEN "1"
type (ssl|tcp|udp|erlang|ssl6|tcp6|udp6|bosh|bosh_ssl|websocket|websocket_ssl ) #REQUIRED>
3. 负载配置
tsung有一个概念叫到达阶段(arrival phase),它有以下几个参数:
<load>
<arrivalphase phase="1" duration="1" unit="minute">
<users arrivalrate="1000" unit="second"/>
</arrivalphase>
<arrivalphase phase="2" duration="2" unit="minute">
<users arrivalrate="10000" unit="second"/>
</arrivalphase>
</load>
这里定义了2个用户到达阶段(arrival phase)
第一阶段的总时长是1分钟,在这一分钟里,每秒钟会有1000个虚拟用户来访问
第二阶段的总时长是2分钟,在这两分钟里,每秒钟会有10000个虚拟用户来访问
4. 添加会话
所谓会话,就是每个用户先后做哪些事情,对于HTTP的测试,当然就意味着发请求,收响应
tsung对每个会话会自动管理cookie
<sessions>
<session name="http-example" probability="100" type="ts_http">
<request>
<http url="/api/v1/model?roomId=158589982254376" method="GET" version="1.1"></http>
</request>
<thinktime min="2" max="10" random="true"/>
</session>
</sessions>
在这个例子里,每个用户的会话会做两件事:
此次主要目的是模拟websocket的请求,那根据业务请求包组装sessions数据如下
<sessions>
<session name="websocket" probability="100" type="ts_http" weight="1">
<request>
<websocket type="connect" path=""/>
</request>
<request subst="true">
<websocket type="message">
{"cmd":"ping","seq":"","data":"","extend":""}
</websocket>
</request>
<thinktime min="1" max="10" random="true"/>
<request>
<websocket type="close"/>
</request>
</session>
</sessions>
此时在服务端并没有产生对应的数据,查看服务端的日志,发现服务端并没有收到消息,因为数据包的问题,消息直接被网关拦截了
了解具体的数据情况,该websocket对处理进行了一层处理
那是否可以直接发送二进制数据呢?
tsung1.7.0版本提供了直接发送binary的数据
<!ELEMENT websocket (#PCDATA | http_header)* >
<!ATTLIST websocket
type (connect | message | close) #REQUIRED
ack (no_ack | parse) #IMPLIED
frame (binary | text) #IMPLIED
origin CDATA ""
subprotocols CDATA ""
path CDATA "/" >
由frame属性设置binary和text两种格式
<session name="websocket" probability="100" type="ts_websocket">
<request subst="true"><websocket type="connect" path="/"></websocket>
</request>
<request subst="true">
<websocket type="message" frame="text">080110001a95020a2432336630653432632d323436662d346131312d616533302d3063316333366137303
36332122039323938653065626539323334613162393665333264666437623364333835651a00220e31383831333239363134387474742a003289017b2261757468223a7b227
5736572223a7b2274696d657374616d70223a2231353837343638353237383032222c227369676e6174757265223a22443937433244444133453436453545364434383245394
5384545383441463933222c22746f6b656e223a223862663035636233373630343464343139386661656664336364613439653538227d7d7d3a09756e646566696e65644a1c3
c6769746272616e63683e2f312e322e302e3c676974636f756e743e5004581e</websocket>
</request>
</session>
</sessions>
此时数据可发送至服务端,建立连接connect可以成功,但是未能解析二进制文件,该数据为text格式
在客户端进行抓包
tcpdump -i any host xxx.xxx.xxx.xxx or port 8080 -v -n -w dump.pcap
抓取的数据包
TCP握手成功,connect数据包ok,发送出去message的数据包为文本格式
尝试修改type为raw格式发送数据
<sessions>
<session name="websocket" probability="100" type="ts_websocket">
<transaction name="open">
<request subst="true">
<raw data="080110001a95020a2432336630653432632d323436662d346131312d616533302d30633163333661373033633212203932393865306562653932
3334613162393665333264666437623364333835651a00220e31383831333239363134387474742a003289017b2261757468223a7b2275736572223a7b2274696d657374616d
70223a2231353837343638353237383032222c227369676e6174757265223a224439374332444441334534364535453644343832453945384545383441463933222c22746f6b
656e223a223862663035636233373630343464343139386661656664336364613439653538227d7d7d3a09756e646566696e65644a1c3c6769746272616e63683e2f312e322e
302e3c676974636f756e743e5004581e" ack="local"></raw>
</request>
</transaction>
</session>
</sessions>
此时请求又被网关层给拦截
查看使用文档Tsung
Example with Websocket as a session type:
<request subst="true">
<websocket type="connect" path="/path/to/ws"></websocket>
</request>
<request>
<dyn_variable name="uid" jsonpath="uid"/>
<!-- send data with text frame, default binary-->
<websocket type="message" frame="text">{"user":"user", "password":"password"}</websocket>
</request>
<request subst="true">
<match do="log" when="nomatch">ok</match>
<websocket type="message">{"uid":"%%_uid%%", "data":"data"}</websocket>
</request>
<request>
<websocket type="message" ack="no_ack">{"key":"value"}</websocket>
</request>
<request>
<websocket type="close"></websocket>
</request>
</session>
根据以上请求格式各种修改,均失败
此后又尝试修改加服务type为ssl等方式,均失败
查看tsung的 issue 信息,没有相关的解决
查看tsung的安装包列表
目前使用的tsung-1.7.0版本已是是最新的包,且在2017年更新,此请求只能暂时搁置了,后续看是否可以修改erlang源码解决该问题或者通过自定义插件的方式实现