Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Achieving Better Performance Results via Remote JMeter Testing

DZone's Guide to

Achieving Better Performance Results via Remote JMeter Testing

Read on to learn a few easy command lines prompts that will allow you to increase the performance of the application you're testing.

Free Resource

In this post, I will discuss how remote (distributed) JMeter testing can be used to achieve better performance results (under certain high load scenarios).

When generating large workloads (e.g. using large numbers of concurrent users), it is possible for a single JMeter instance to become unstable and this may affect the performance results that it generates. In JMeter, it is possible to control multiple, remote JMeter engines (called JMeter servers) from a single JMeter client (see [1]). This will allow us to replicate a performance test across multiple machines and generate larger loads.

Clustering JMeter

Let’s first have a look at how to cluster JMeter so that one instance of JMeter can control the remote JMeter instances. There are multiple ways to cluster JMeter and one of them is discussed below.

Starting the Slaves (Server Instances)

The slave instances are the nodes where the actual performance tests are run. These nodes are also called server instances. To start the servers, type in the following command on the server instances’ terminal

./jmeter-server -djava.rmi.server.hostname=ipaddress 

Note that the IP-address is the IP address of the slave node.

The following line will appear on the terminal

Starting the Client (Master)

JMeter client instance can control remote JMeter (server) instances, and collect the data from them. To start the JMeter client, type in the following on the client instance’s terminal:

./jmeter.sh -n -t perf_test.jmx -R serverip1, serverip2, serverip3 -l pert_test.jtl

serverip1 is the IP address of the JMeter server 1.

serverip2 is the IP address of the JMeter server2, and so on.

perf_test.jmx is the script which will be run on each JMeter server instance.

If the script has parameters, then use -G to set these parameters (instead of J which is used for non-remote testing). For example, the following command sets the Concurrency parameter at 50:

./jmeter.sh -GConcurrency=50 -n -t perf_test.jmx -R serverip1, serverip2 -l pert_test.jtl

While the test is running, the test results will appear on the client's terminal. Note that concurrency is 100 (50 * numbers of servers, where numbers of servers = 2).

Other Configurations

Increase JMeter Server Heap Memory

To minimize the effect of JMeter GC on the performance results, increase the JMeter server heap memory if possible.

Case Study: Netty Performance Test

The following table shows the performance results for a simple NETTY server. The performance test was done using 2 JMeter (server) instances (with clustering) and a single JMeter instance. This test was run on EC2 and each JMeter instance and NETTY were run on separate EC2 instances.

The following are my key observations:

  • There is a significant improvement in TPS and average latency when using the clustered setup (i.e. remote testing).

  • There is a significant reduction in the load average on the JMeter instances when using multiple JMeter instances.

  • There is an increase in the maximum latency when using remote testing (we are currently looking into this. One observation was that if we reuse the connections then we can reduce this number significantly).

Conclusion

In this post, I have presented how to use multiple JMeter instances for performance testing. We noticed that remote JMeter testing can achieve better performance results. There is an increase in maximum latency when not reusing connections and this needs to be further investigated.

[1] http://jmeter.apache.org/usermanual/remote-test.html

Topics:
jmeter ,low latency ,throughput ,performance ,netty

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}