Saturday, October 17, 2009

How to use jMeter in server mode over an SSH tunnel

INTRODUCTION

Apache JMeter is open source software, a 100% pure Java desktop application designed to load test functional behavior and measure performance. It was originally designed for testing Web Applications but has since expanded to other test functions. (http://jakarta.apache.org/jmeter/)

jMeter can be run in "GUI", "non-GUI" and "server" modes. You can control and monitor multiple instances of  jMeter running in server mode with a single instance that is running in GUI mode. You may want to do this over a secure SSH connection when connecting to remote servers.

(This how-to covers tunneling of the jMeter instance-to-instance communication, not the jMeter-to-the-tested-application communication.)

THE SOLUTION

jMeter uses RMI with callbacks for inter-instance communication. We will configure jMeter and the SSH tunneling based on the great article "SSH Tunneling for Java RMI, Part-II" by Pankaj Kumar.

We will need to:
1. Force jMeter on server side (server mode) and client side (GUI mode) to bind to localhost
2. Set the RMI registry port and the method  invocation port of jMeter server to an arbitrary value
3. Force jMeter client to listen for RMI callbacks on an arbitraty port
4. Tunnel the RMI ports

To achieve points 1 and 3 we will need to patch jMeter source code and build it. The patch applies only to jMeter version 2.3.4.

I will suggest my jMeter code changes to be incorporated into the jMeter project. This may take some time and the changes may be even refused, so in between the patch is probably the only way how to tunnel over SSH. It is possible that if the code will be accepted by jMeter project, it will be somehow modified and the configuration for the next versions will be different.

WHAT THE PATCH DOES

- Adds jMeter parameter server.rmi.localhostname - jMeter by default 1) binds to the host's hostname and 2) refuses to bind to localhost. If this parameter is set, jMeter will bind to the specified ip/hostname and (only if this parameter is set) won't complain even if it is localhost.

- Adds jMeter parameter client.rmi.callbackport - jMeter will listed on this port for RMI callbacks.

PREREQUISITIES

JDK
Ant
SSH client, e.g. Putty (http://www.chiark.greenend.org.uk/~sgtatham/putty/)

HOW TO

Let's assume that:
- server RMI registry port is 55501
- server RMI method invocation port is 55511
- client RMI callback port is 55512

1. Download both the jMeter 2.3.4 binaries and source code (http://jakarta.apache.org/jmeter/) and extract them into the same directory of your choice

2. Download my patch and copy it over the original jMeter source code.

3. Build jMeter (http://wiki.apache.org/jakarta-jmeter/BuildingJMeter)

4. Copy it to both the server and client machine

5. Edit the server jmeter.properties:
server_port=55501
server.rmi.localhostname=127.0.0.1
server.rmi.localport=55511

6. Edit the client jmeter.properties:
remote_hosts=127.0.0.1:55501
client.rmi.callbackport=55512

You will also want to switch to batch mode to lower the network traffic:
mode=Batch
num_sample_threshold=250

7. Configure the tunnelling
Local port: 55501 -> 127.0.0.1:55501
Local port: 55511 -> 127.0.0.1:55511
Remote port: 55512 -> 127.0.0.1:55512

8. Start the jMeter server and client using (to associate remote stubs with localhost):
server (example for linux): ./jakarta-jmeter-2.3.4/bin/jmeter-server -Djava.rmi.server.hostname=127.0.0.1 &
client (example for win): jakarta-jmeter-2.3.4\bin\jmeter.bat -Djava.rmi.server.hostname=127.0.0.1

Done!

Next part: How to use jMeter in server mode over an SSH tunnel - Part 2 - Mutliple server instances