This is the fifth part in a series of posts where I’m covering my experiences in working with the JMeter application to perform load testing on a web based application. The first, second, third and fourth parts in the series can be view here, here, here and here respectively. In this post I’m going to address expanding my testing so that the load was being generated from more than one machine.
Modern computer architectures are moving away from faster CPUs and towards a multiple CPU approach to providing more capacity. Most current desktop machines would contain 2 cores, with some high end servers having 8, 16 or more. Despite this there are still limitations to the amount of load that these machines can be used to generate. As I noted in my previous post in this series, memory is a key resource here and, although 64 bit architectures have raised the bar on it’s availability, it’s uncommon to have access to machines with more than 16Gb of RAM. Ultimately what this means for load testing is that load generation is going to have to be spread across multiple machines.
I’d assembled my test script on a single machine and, while this was quite a powerful machine as desktops go, I’d hit a wall on the load I was able to generate from it at around 1500 users. The machine was running a number of other applications (including an Oracle database server instance) and I had to hand the machine over exclusively to the load test for the duration of the run. I didn’t feel that I could successfully push it further. I flagged the fact that I’d need extra machines to my boss and the search for extra work horses was kicked off.
In the end I acquired a good selection of machines to perform the testing. My own machine is a quad core 64 bit Windows desktop with 4Gb of RAM. I managed to obtain one other identical machine and a third machine with a similar specification but more RAM. Once I’d identified the machines I would be working with I needed to configure them for use. The obvious first step was software installation. I installed the latest Java Runtime Environment on the extra machines and then downloaded and installed the JMeter application. I updated the jmeter.properties file on all machines to allow them to feed back results in batch mode and upped the memory given to the Java instance running JMeter to 1Gb in the jmeter.bat file.
JMeter comes with a jmeter-server.bat file to run the application in server mode for distributed testing but I found this didn’t work for me. I got the feeling that the problems originated from the fact that their were spaces in the path to my Java installation. To get around this I put together a separate script that fired up the Java RMI registry application and then execute the jmeter.bat file in server mode. With this in place I had all the components I needed to start doing some distributed load testing.
I intended to use my own machine both for load generation and for results data so I needed to configure the two other machines in my cluster in my local copy of the jmeter.properties file. To do this I simply had to add the IP addresses of the test machines to the remote_hosts entry in this file. This entry contains a value of 127.0.0.1 by default, which represents the local host, so I didn’t have to explicitly add the IP address of my own machine. The JMeter documentation for distributed testing has warnings about subnets and firewalls but I found that these did not apply in my case. Once I’d configured the jmeter.properties file I restarted the JMeter application and was able to see my configured entries under the Run -> Remote Start menu. There’s also a Run -> Remote Start All option for kicking off all configured entries simultaneously - this was the option I would use.
When running locally JMeter has a small counter of active threads that it displays in the upper right hand corner of it’s window. Unfortunately this counter is not updated when running in distributed mode, even if your local machine is part of the load generation. The indicator still goes from grey to green and back again to show the start and end of testing though.
Initially I had some issues with the application configuration while trying to do distributed testing and this highlighted what I consider a weakness in JMeter functionality. I’d set my test plan to stop on errors but, if an error did occur on a remote load generation machine while I was testing, the test stopped but the application did not clean up properly. In such a case the remote instance would be left hanging and uncontactable. I found that I had to shutdown and restart the RMI registry and JMeter server on the remote machine to get around this. If this happens a lot it can be very frustrating.
Once I had all issues ironed out, running in distributed mode was almost as simple as running locally. The only thing to note is that JMeter doesn’t divide the work load specified across the available remote machines. Instead it creates the specified work load on each of the remote machines. In my case I had 3 load generation machines and wanted to generate a total of 3000 users against my test application. This meant configuring the test plan to start 1000 users.
This is my final post in the series on JMeter and I have to say over all I was impressed. Load testing was a task that I was not looking forward to but JMeter has helped make the process a lot less arduous than I’d originally imagined. As an open source tool it may not be as slick as some of the commercial offerings out there but it shouldn’t be undervalued either. There’s clearly been a lot of work gone into JMeter that insulates the end user from a great deal of the underlying complexity. Having said that its a tool that is perhaps better suited to users that have a more technical view, with an understanding of protocols like HTTP or how to use regular expressions being examples of the kind of knowledge that is beneficial in using JMeter. Given the option I’d certainly be happy to use JMeter again if the need arises.