load test your drupal application scalability with apache jmeter
when making scalability modifications to your system, it's important to quantify their effect, since some changes may have no effect or even decrease your scalability. the value of advertised scalability techniques often depends greatly on your particular application and network infrastructure, sometimes creating additional complexity with little benefit.
apache jmeter is a great tool to simulate load on your system and measure performance under that load. in this article, i demonstrate how to setup a testing environment, create a simple test and evaluate the results.
as usual, all code and configurations have been tested on debian etch but should be useful for other *nix flavors with subtle modifications. also, although i'm discussing drupal testing, the method below really applies to any web application.
the testing environmentyou should install and run the jmeter code on a server that has good resources and has a high-bandwidth, low-latency network access to your application server or load balancer. the maximum load that you can simulate is clearly constrained on these parameters. so are the accuracy of your timing results. therefore, for very large deployments you may need to run multiple non-gui jmeter instances on several test machines, but for most of us, a simple one test-machine configuration will suffice, i recently simulated over 12K pageviews/minute from a modest single-core server that wasn't close to capacity.
jmeter has a great graphical interface that allows you to define, run and analyze your tests visually. a convenient way to run this is to ssh to the jmeter test machine using x forwarding, from a machine running an x server. this should be as simple as issuing the command:
$ ssh -x testmachine.example.com
$ sudo apt-get install xserver-xorg-core xorg
x forwarding can become unbearably slow once your test is running, if the test saturates your test server's network connection. if so, you might consider defining the test using the gui and running it on the command line. read more about remote testing on the apache site, and on command line jmeter later in this article.
setting up the test server - download and install java
jmeter is a 100% java implementation, so you'll need a functional java runtime install.
if you don't have java 1.4 or later, then you should start by installing it. to do so, make sure you've got a line in
/etc/apt/sources.list like this:
deb http://ftp.debian.org/debian/ etch main contrib non-free
apt-get update. once you've done this, do:
$ sudo apt-get install sun-java5-jre
installation on vista is as easy as downloading and installing the latest zip from
http://jakarta.apache.org/site/downloads/downloads_jmeter.cgi, unzipping it and running jmeter.bat. please don't infer that i'm condoning or suggesting the use of windows vista ;)
setting up the test server - download and install jmeter
next, download the latest stable version of jmeter from the jmeter download page, for example:
$ wget http://apache.mirrors.tds.net/jakarta/jmeter/binaries/jakarta-jmeter-2.3.1.tgz
$ tar xvfz jakarta-jmeter-2.3.1.tgz
$ cd ./jakarta-jmeter-2.3.1/bin
if you are having problems running jmeter, see the troubleshooting section at the end of this article.
setting up a basic testjmeter is a very full featured testing application. we'll scratch the surface of it's functionality and setup a fairly simplistic load test. you may want to do something a bit more sophisticated, but this will at least get you started.
to create the basic test, run jmeter as described above. the first step is to create a "thread group" object. you'll use this object to define the simulated number of users (threads) and the duration of the test. right mouse click the test plan node and select:
add -> thread group
specify the load that you'll exert on your system, for example, pick 10 users (threads) and a loop count (how many times each thread will execute your test). you can optionally modify the ramp up period e.g. a 10s ramp up in this example would create one new user ever second.
now add a sampler by right mouse clicking the new thread group and choosing:
add -> sampler -> http request. make sure to check the box "retrieve all embedded resources from html files", to properly simulate a full page load.
now add a listener to view the detailed results of your requests. the "results tree" is a good choice. add this to your thread group by selecting:
add -> listener -> view results tree. note that after you run your test, you can select a particular request in the left panel and then select the "response data" tab on the right, to verify that you are getting a sensible response from your server, as shown below.
finally let's add another listener to graph our result data. choose:
add -> listener -> graph results. this produces a graph similar to the graph on the right.
if you want to create a more sophisticated test, you'll probably want to create realistic use scenarios, including multiple requests spaced out using timers, data creation by logged in users etc. you'll probably want to verify results with assertions. all of this is relatively easy, and you can read more on apache's site about creating a test plan. you can get information on login examples and cookie support here. you can also read the follow up to this blog: load test your drupal application scalability with apache jmeter: part two
running your testcontrolling your test is now a simple matter of choosing the menu items:
run -> start,
run -> stop,
run -> clear alletc. it's very intuitive. while your test is running, you can select the results graph, and watch the throughput and performance statistics change as your test progresses.
if you'd like to run your test in non-gui mode, you can run jmeter on the command line as follows:
$ jmeter --nongui --testfile basicTest.jmx --logfile /tmp/results.jtl
basicTest.jmx, and ouput the results of the test in a file called
/tmp/results.jtl. once the test is complete, you could, for example, copy the results file locally and run jmeter to visually inspect and analyse the results, with:
$ jmeter --testfile basicTest.jmx
you may then use the listener of choice (e.g. "graph results") to open your results file and display the results.
interpreting your drupal resultsmost production sites run with drupal's built-in caching turned on. you can look at your performance setting in the administration page at:
http://www.example.com/admin/settings/performance. this caching makes a tremendous difference to throughput, but when users are logged in, they bypass this cache.
therefore, to get a realistic idea of your site performance, it's a good idea to calibrate your system with caching on and caching off, and linearly interpolate the results to get a true idea of your maximum throughput. for example, if your throughput is 1,000 views per minute with caching, and 100 without caching and at any given point in time 50% of your users are logged in, you could estimate your throughput at (1000 + 100) / 2 = 550, that is 550 views per minute.
alternatively, you could build a more sophisticated test that simulates close-to-realistic site access including logged-in sessions. clearly, the more work you put into your load tests, the more accurate your results will be. see the followup article for details on building a more sophisticated test.
an example test - would a static file server or cdn help your application?
jmeter allows you to easily estimate the effect of configuration changes, sometimes without actually making the changes. recently i read robert douglass' interesting article on using lighttpd as a static file server for drupal, i was curious how much of a difference that would make.
simply un-checking the "retrieve all embedded resources from html files" on the http request allowed me to simulate all the static resources coming from another (infinitely fast) server.
for my (image intensive) application the results were significant, about a 3x increase in throughput. clearly the real number depends on many factors including the static resources (images, flash etc) used by your application and the ratio of first time to repeat users or your site (repeat users have your content cached). it seems fair to say that this technique would significantly improve throughput for most sites and presumably page performance would be significantly improved too, especially if the static resources were cdn hosted.
troubleshooting your jmeter installif you are having problems with your jmeter install, then:
make sure that the java version you are running is compatible i.e. 1.4 or later, by:
$ java -version
java version "1.5.0_10"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_10-b03)
make sure that you have all the dependencies installed, if you get the error "cannot load awt toolkit: gnu.java.awt.peer.gtk.gtktoolkit", you might you might have to install the gcj runtime library. do this as follows:
$ sudo apt-get install libgcj7-awt
if jmeter hangs or stalls, you probably don't have the right java version installed or on your path.
if you're still having problems, take a look in the application log file
jmeter.log for clues. this gets created in the directory that you run jmeter in.
if you are having problems getting x forwarding to work, make sure that it is enabled in your sshd config file e.g.
/etc/ssh/sshd_config. you should have a line like:
if you change this, don't forget to restart the ssh daemon.
- jmeter user manual
- jmeter home
- jmeter binary downloads
- creating a jmeter test plan
- jmeter component reference
if you'd like to build a more sophisticated test, take a look at my next blog: load test your drupal application scalability with apache jmeter: part two.
tech blogif you found this article useful, and you are interested in other articles on linux, drupal, scaling, performance and LAMP applications, consider subscribing to my technical blog.
thanks to curtis (serverjockey) hilger for introducing me to jmeter.