An open-source multi-protocol distributed load testing tool.
Tsung, developed in Erlang, is a high-performance benchmark framework for various protocols including HTTP, WebDAV, SOAP, PostgreSQL, MySQL, LDAP, Jabber/XMPP, etc.
Tsung can be distributed on several client machines and is able to simulate hundreds of thousands of virtual users concurrently.
The first step is to install Tsung.
If your system doesn't have the latest version,
which is 1.6.0, you can download the source package from the below link and then compile.
configure && make && make install && complete
Tsung does load and stress testings based on the parameter content in the configuration folder of xml.
The default configuration file is ~/.tsung/tsung.xml
If the original folder is empty，there are several saample files in /usr/share/doc/tsung/examples,
The configuration for http is http_simple.xml
Next, about some key configurations：
How clients are generated:
<clients> <client host="localhost" use_controller_vm="true" maxusers="30000"/> </clients>
Tsung can be run by a number of virtual machines，the client configuration indicates the maximum clients number on this specific machine,
if use_controller_vm is true, then Tsung will generate a new VM when the clients number reaches mmaxusers.
<servers> <server host="test.com" port="80" type="tcp"></server> </servers>
<servers> could be configured with its according info, or with clusters, such as the below example:
<servers> <server host="server1" port="80" type="tcp" weight="4"></server> <server host="server2" port="80" type="tcp" weight="1"></server> </servers>
In this case, Tsung will choose a server to send the request according to the weight value.
The System-monitoring Service can acquire relevant information of the tested cpu, memory, load, database of server after the configuration. It could also be configured as the monitoring system for erlang and snmp.
<monitoring> <monitor host="garden" type="erlang"> <mysqladmin port="3306" username="root" /> </monitor> </monitoring>
<load> could be configured with the requirement, which can design various phases that appointed by the value of PHASE. DURATION is the period of the testing, and the UNIT means unit.
The maxnumber of users tag limits the generated max amount of the users, interarrival=”0.02” means each new user being generated every 0.02 second. Users execute the requests as the order of the session configuration.
<load> <arrivalphase phase="1" duration="3" unit="minute"> <users maxnumber="100" interarrival="0.02" unit="second" ></users> </arrivalphase> </load>
Options could be configured with some requests info, such as agent.
<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>
<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&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&item_id=%%_itemid%%&content=%%_content%%"></http> </request> </transaction> </session> </sessions>
<sessions> could be configured with several sub-sessions to test multiple apis. When setting up the probability tag, the total value of all the probablility tags must be exactly 100, while the type of request is http.
<for from="1" to="@loop" incr="1" var="counter">
The request times can be set by FOR as followed.
Futher details could also be set here, expecially the random number in the parameters of request.
<setdynvars sourcetype="random_number" start="20" end="5000000"> <var name="xxx" /> </setdynvars> <setdynvars sourcetype="random_string" length="10"> <var name="xxx" /> </setdynvars>
Call by the format of “%%_xxx%%” .
Caution: if you want to use the random number, the “subst=”true” must be set in the parameters of request, otherwise, the random number won't be referred to successfully. The random number could also be read from file, such as CSV.
<http_header name="Authorization" value="111"/> <http_header name="Cookie" value="authToken=%%_auth_token%%; Path=/"/> <!-- content-Type：Codes could also be written like the below example when the format is json. --> <http_header name="Content-Type" value="application/json"/>
The header data can be defined in the http tag:
The interval of two different requests could be defined in the thinktime tag.
Besides, different transactions can also be defined and then different specific information of transactions will be shown in the results accordingly.
After testing, enter the matched result document of log folder.
Then you can get the result form that we want.
The generated report.html is the final reports.
Some general info in Main Statistics being:
- simultaneous users and opened TCP/UDP connections
Axle Y indicates the users amount per sec; Tsung can generate some users in every sec. The stats are updated every 10 seconds. All the patterns start from 0.
- http code response rate
Axle Y indicates the response per sec. The "200" in the right top corner is the http status code. If multi status codes exist at the same time, there will be multi-colored curves.
- mean request duration
Axle Y indicates the response time of the interface, the unit is micro second. The line of request says the entire time of request. The line of connect shows the time of creating a tcp connection.
After a few rounds of testing, we found out that the maximum writing frequency of our system is about 80 requests per min, without any optimized solutions, such as cache and queue, as we just write in the database directly. With the initial amount of tasks being relatively few, the data has satisfied the production environment so far. Based on the testing results we have improved some logical SQL to make the system be able to deliver a much higher and more effective performance.
BTW, we also used innotop as the monitor tool of mysql and htop as the monitor of system load.