JMeter remote testing on AWS EC2

Posted: August 15, 2023

Introduction

Running JMeter in a single machine limits our capacity to load applications. We can either vertically or, horizontally scale the infrastructure to match our testing needs.

In this tutoral we will cover the installation of JMeter in a distributed architecture on AWS EC2 instances.

There are two roles in a JMeter’s distributed architecture: 

  • Controller (client) orchestrates the tests and aggregates the results.
  • An Injector (server) does the heavy lifting by actually loading the target application and sending back its results to the Controller. 

Prerequisites

  • Controller and injector machines must have the same version of Java and JMeter installed.
  • EC2 instances must be in the same subnet.

Download

JMeter is open source/free software load tool developed by Apache and can be downloaded here, and is portable.

Download a copy of JMeter in each of the EC2 instances (controller and injectors)

Configuration

Specify the IP addresses of the remote hosts (only for the Controller)

Choose an instance to serve as a controller, then, go to jmeter.properties (under the bin directory) and add the IP adresses of the injectors as remote_hosts (a restart of JMeter maybe required):

# Remote Hosts - comma delimited
remote_hosts=172.31.25.xx,172.31.88.xx

Configure or deactivate SSL for RMI

In the controller’s JMeter installation, run bin**/**create-rmi-keystore.sh and answer the questions. “rmi“ should be the answer to the first question, the rest isn’t important, at the end of this process an rmi_keystore.jks file will be generated. Copy the rmi_keystore.jks file under the **bin** directory in all remote hosts (the generated key-pair is valid for seven days). For more information check out JMeters’ official documentation.

OR Disable SSL for RMI in all hosts:

# Set this if you don't want to use SSL for RMI                                                                       
server.rmi.ssl.disable=true

Configure JMeter/RMI ports

JMeter/RMI requires multiple connection and ports to function properly:

  • A connection from the client (controller) to the server (injector), the default is 1099.
  • A reverse connection in order to return sample results from the injectors to the controller. A base port for client.rmi.localport must be specified, JMeter will open up to three ports beginning with the port defined+1. For example if client.rmi.localport\=50000 then JMeter may open ports 50001 to 50003.

  If we leave client.rmi.localport\=0, JMeter will choose ports randomly which makes it impossible to authorize in security groups inbound rules.

# Parameter that controls the base for RMI ports used by RemoteSampleListenerImpl and RemoteThreadsListenerImpl (The Controller)
client.rmi.localport=50000 
  • By default, RMI uses a dynamic port for the JMeter Server Engine. To easily authorize the connection in the security groups inbound rules we should also specify a port for the JMeter Server Engine in all hosts:
# To use a specific port for the JMeter server engine, define the following property before starting the server:
server.rmi.localport=4000

Ports authorization

Since we don’t have to worry about security groups’ outbound rules, the ports mentioned above must be allowed only in the appropriate security groups’ inbound rules:

  • Controller SG: 4000 (ServerEngine), 4445 (StopTest) and 50001-50003 (ReverseConnection) controller inbound flou
  • Injectors SG: 1099 and 4000 injector inbound flou

Run a distributed test

First you have to run the JMeter server on every injector, here is an example:

JVM_ARGS="-Xms512m -Xmx512m" ./jmeter-server

Then, from the controller here is simple run : 

./jmeter.sh -n -t test_script.jmx -l result_file.csv -R <remote_host_ip1>,<remote_host_ip2>

HEAP optimization

By default JMeter sets the Xms and Xmx to 1g, which is very low for most hosts. 

  • For GNU/Linux based operating systems you can set the JVM_ARGS as shown above.
  • For Windows to optimize JMeter’s performance set HEAP=-Xms4g -Xmx6g -XX:MaxMetaspaceSize=256m in jmeter.bat, depending on you hosts memory.  

For more information please check JMeter's official documentation