Know the options, including my shell script that does it all, each step explained
- Installation options
- Blazemeter SaaS
- Manually download installer
- Images from DockerHub.com
- Build by Dockerfile
- Run BASH script
- Manual step-by-step install
- Videos on YouTube
This tutorial introduces JMeter by explaining each setp of an automated script for imposing artificial load on a server created to run RabbitMQ.
In an internet browser (Google Chrome, Mozilla Firefox, Apple Safari, etc.), open
BTW: Historically, JMeter first became available December 2003 as the “Jakarta” project until it became the full-fledged product. Its previous URL is automatically routed from http://jakarta.apache.org/jmeter
For now, just look at the webpage header: JMeter is open-sourced by the Apache Foundation project. This means JMeter is offered free.
The “J” in JMeter refers to the Java Virtual Machine (JVM). JMeter is written in Java. This makes JMeter multi-platform on Windows, MacOS, Linux.
“Meter” refers to being akin to parking meters that measure time. It is said that “Time is money” because when a user waits for the system to respond, he or she is not productive getting work done. And the longer that a transaction takes to respond, the more servers are needed to server everyone.
Each JMeter program running can emulate hundreds of human users typing and clicking through a web application because JMeter mimics just the network traffic exchanged between clients and servers. We make JMeter do that in order to measure how the application server will likely behave under load when running in production. The amount of load imposed by JMeter is often described in terms of the number of real users JMeter emulates. Each fake user may be setup to submit transactions quicker than real users.
From the Apache web page:
Wikipedia lists the version history:
Note version 4 became available on Feb. 10, 2018 to support Java 9.
There are several ways to obtain a running instance of JMeter, listed from easiest to most difficult:
But customers at some companies do not trust public clouds. So…
This is the approach shown by many tutorials (see below)
C) Pull an image from Docker Hub within a Google Compute or AWS cloud instance.
D) Use the Dockerfile to build your own Docker image containing JMeter.
CAUTION: If you are in a large enterprise, confer with your security team before installing. They often have a repository such as Artifactory or Nexus where installers are available after being vetted and perhaps patched for security vulnerabilities.
You don’t need a local machine if you use the cloud service
You can’t use blazemeter if your server is behind a firewall because blazemeter is a Saas service running on the public internet.
The SaaS vendor was purchased by CA in 2017.
Users of Blazemeter can use their add-on test framework.
Blogs about this:
Manually download installer
Even if you’re not intending to download, go here to see the dates of each version available for download:
At time of writing:
In Finder, double-click the file to unzip to folder:
Move the folder to a folder with a path containing no spaces, such as:
PROTIP: Putting the folder in your home folder would avoid issues with permissions.
cd ~/Downloads mv apache-jmeter-3.3 ~/jmeter cd jmeter
Images from DockerHub.com
A Docker image is ready to run, after having Docker build it based on a Dockerfile.
There are many JMeter images on DockerHub.
The most popular:
docker pull cirit/jmeter
BLAH: As of this writing, it runs the older Jmeter 2.13 + Debian OS + Java Server JRE 8 on
Another image containing a JMeter server include:
docker pull justb4/jmeter
The image used in the flood.io SaaS service is:
docker pull floodio/jmeter
Videos about this topic:
Build by Dockerfile
PROTIP: Although it takes more time, this approach is often necessary to incorporate new security patches in all levels of the tech stack, from the operating system up. Building an image Dockerfile means that you have the very latest versions of all components.
Installing within a Docker container means you are not “cluttering up” you native operating system. In case a particular combination does not work, you can change it without jepordizing your laptop being in a working state.
Rather than repeating the instructions here, for AWS and Blue Ocean clouds, see https://gist.github.com/hhcordero/abd1dcaf6654cfe51d0b
The script below can be invoked to setup either a Docker image or your local laptop.
Run BASH script
PROTIP: This script is the starting point for invoking JMeter using continuous integration such as TeamCity or Jenkins.
If you’re on a Mac, all the manual steps described below are automatically performed in the script.
In a Terminal, navigate to the folder under which a new folder is created. The script creates this under your user home page:
mkdir temp cd ~/temp
Type or copy and paste this command on your Terminal:
sh -c "$(curl -fsSL https://raw.githubusercontent.com/wilsonmar/JMeter-Rabbit-AMQP/master/jmeter-rabbitmq-setup.sh)"
Before installing each item, the script first tests if the item has already been installed.
In this tutorial and script, we load test a RabbitMQ message broker to accept and forward messages, like a physical post office: where you put the mail that you want posting in a post box, you can be sure that the Postman will eventually deliver the mail to your recipient. In this analogy, RabbitMQ is a post box, a post office, and a postman.
Manual step-by-step install
PROTIP: JMeter is written in Java, so it can be run on Windows, Mac, and Linux.
If you were to manually click at http://www.oracle.com/technetwork/java/javase/downloads/index.html installation would be to:
But instead use the automated approach:
First see what version is considered the latest 64-bit Java Development Kit (JDK) by brew:
brew cask info java
BLAH: We don’t want to install version 9 just yet because when JMeter is installed, it throws up this error:
Error: Java version is too low to run JMeter. Needs at least Java >= 1.8.0.
If you have it already installed, uninstall it.
PROTIP: Install not the latest 64-bit Java Development Kit (JDK), but the last stable v1.8 version:
brew tap caskroom/versions brew cask install java8
==> Caveats This Cask makes minor modifications to the JRE to prevent issues with packaged applications, as discussed here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=411361 If your Java application still asks for JRE installation, you might need to reboot or logout/login. Installing this Cask means you have AGREED to the Oracle Binary Code License Agreement for Java SE at https://www.oracle.com/technetwork/java/javase/terms/license/index.html ==> Satisfying dependencies ==> Downloading http://download.oracle.com/otn-pub/java/jdk/8u152-b16/aa0333dd30 ######################################################################## 100.0% ==> Verifying checksum for Cask java8 ==> Installing Cask java8 ==> Running installer for java8; your password may be necessary. ==> Package installers may write to any location; options such as --appdir are i Password: ==> installer: Package name is JDK 8 Update 152 ==> installer: Installing at base path / ==> installer: The install was successful. 🍺 java8 was successfully installed!
Provide your administrator password when prompted.
Confirm it works by returning the version of the Java compiler installed. In version 9:
Alternately, in version 8, use a single dash:
On a Mac, with a Terminal at any folder, install:
brew install jmeter --with-plugins
Notice in the response that there is a different version of the installer for each version of the operating system. At time of this writing:
==> Downloading https://homebrew.bintray.com/bottles/jmeter-3.3.el_capitan.bottle.tar.gz ######################################################################## 100.0% ==> Pouring jmeter-3.3.el_capitan.bottle.tar.gz 🍺 /usr/local/Cellar/jmeter/3.3: 2,855 files, 101.7MB
PROTIP: Behind the scenes, downloads are from:
The script saves the file path other scripts will be using to invoke JMeter just installed:
export JMETER_HOME="/usr/local/Cellar/jmeter/3.3" echo $JMETER_HOME ls $JMETER_HOME
The response (at time of writing):
/usr/local/Cellar/jmeter/3.3 INSTALL_RECEIPT.json NOTICE bin LICENSE README.md libexec
Alternately, if you are to be using JMeter on your machine, add the export in your Mac’s ~/.bash_profile file.
Let’s summarize what folders are in a folder, install the tree utility:
brew install tree
Show the first level tree:
tree -L 1
- bin contains executables, jar, and properties files
- extras contains miscellaneous files including samples using the Apache Ant tool
- lib contains library utlity jar files
- lib/ext contains JMeter components and add-ons
- licenses contains legal text
- printable_docs contains the usermanual in html and a demos folder containing jmx files
Run bash script
To obtain a JMeter project to test a RabbitMQ service:
git clone https://github.com/wilsonmar/JMeter-Rabbit-AMQP --depth=1 cd JMeter-Rabbit-AMQP
PROTIP: The depth parameter ensures that only the most recent version of files are downloaded instead of all the history.
NOTE: The repo was cloned from https://github.com/jlavallee/JMeter-Rabbit-AMQP because of a deprecation error in build.xml updated to Java 1.8 from 1.5:
<property name="target.java.version" value="1.5"/> <property name="src.java.version" value="1.5"/>
Its author Vitor Campos from Brazil (firstname.lastname@example.org) no longer has an active account on GitHub.
I also added the Bash script described above.
Let’s see what was built, using the tree utility (which we installed above):
The tree output:
├── LICENSE ├── README.md ├── build.xml ├── examples │ └── RPC_Load_Test.jmx ├── ivy.xml └── src └── main └── com └── zeroclue └── jmeter └── protocol └── amqp ├── AMQPConsumer.java ├── AMQPPublisher.java ├── AMQPSampler.java └── gui ├── AMQPConsumerGui.java ├── AMQPPublisherGui.java └── AMQPSamplerGui.java
The convention for Java program is to have programming source files within the src folder. The folder src/main/com/zeroclue/jmeter/protocol/amqp/ contains Java code to recognize and respond to the AMQP (Advanced Message Queuing Protocol) used by RabbitMQ services.
The companion to that set of programs are within the folder “gui”.
import statements in the code are dependencies that need to be downloaded as well before the Java code is compiled into classes that Java Virtual Machine runs. That is done by a build automation.
When a project’s files include a build.xml file for ant or maven program to specify download of libraries needed by source code in the src folder.
Install the ant program and run it:
brew install ant
At time of this writing:
==> Downloading https://homebrew.bintray.com/bottles/ant-1.10.1.el_capitan.bottle.tar.gz ######################################################################## 100.0% ==> Pouring ant-1.10.1.el_capitan.bottle.tar.gz 🍺 /usr/local/Cellar/ant/1.10.1: 1,628 files, 36.8MB
PROTIP: https://github.com/jfifield/ant-jmeter provides examples of how to use ant to run JMeter.
Edit to view the build.xml file.
Run the ant program which knows to read the build.xml file:
At time of writing, when running on Java 8, the many console messages end with:
--------------------------------------------------------------------- | | modules || artifacts | | conf | number| search|dwnlded|evicted|| number|dwnlded| --------------------------------------------------------------------- | build | 119 | 108 | 108 | 33 || 86 | 86 | | runtime | 119 | 108 | 108 | 33 || 86 | 86 | --------------------------------------------------------------------- compile: [echo] Compiling [mkdir] Created dir: /Users/wilsonm/gits/JMeter-Rabbit-AMQP/target/classes [javac] Compiling 6 source files to /Users/wilsonm/gits/JMeter-Rabbit-AMQP/target/classes [javac] warning: [options] bootstrap class path not set in conjunction with -source 1.5 [javac] warning: [options] source value 1.5 is obsolete and will be removed in a future release [javac] warning: [options] target value 1.5 is obsolete and will be removed in a future release [javac] warning: [options] To suppress warnings about obsolete options, use -Xlint:-options. [javac] 4 warnings package: [mkdir] Created dir: /Users/wilsonm/gits/JMeter-Rabbit-AMQP/target/dist [jar] Building jar: /Users/wilsonm/gits/JMeter-Rabbit-AMQP/target/dist/JMeterAMQP.jar BUILD SUCCESSFUL Total time: 2 minutes 17 seconds
BTW, if ant is run again, the search and “dwnlded” would be zero because they are already downloaded.
CAUTION: When running on Java 9, this error message appears before the compile fails:
compile: [echo] Compiling [javac] Compiling 6 source files to /Users/wilsonm/gits/wilsonmar/JMeter-Rabbit-AMQP/target/classes [javac] warning: [options] bootstrap class path not set in conjunction with -source 1.5 [javac] error: Source option 1.5 is no longer supported. Use 1.6 or later. [javac] error: Target option 1.5 is no longer supported. Use 1.6 or later.
Let’s see what was added by the build, using the tree utility installed earlier:
├── ivy │ └── ivy.jar └── target ├── classes │ └── com │ └── zeroclue │ └── jmeter │ └── protocol │ └── amqp │ ├── AMQPConsumer.class │ ├── AMQPPublisher.class │ ├── AMQPSampler.class │ └── gui │ ├── AMQPConsumerGui.class │ ├── AMQPPublisherGui.class │ └── AMQPSamplerGui.class └── dist └── JMeterAMQP.jar
Ant installs Apache Ivy, which is used instead of Maven for resolving dependencies. This avoids the alternative installation using:
curl -L -O http://search.maven.org/remotecontent?filepath=org/apache/ivy/ivy/2.3.0/ivy-2.3.0.jar
ivy.jar is run by Ant to resolve dependencies specified in file ivy.xml.
Also, the build created a target folder containing java executable class files. These are packaged into the JMeterAMQP.jar within the dist folder. That jar is what the JVM runs.
Copy JMeterAMQP.jar into JMeter
Copy the JMeterAMQP.jar just compiled into where JMeter stores its built-in extension executables:
\* From the root folder within JMeter-Rabbit-AMQP-master :: cp target/dist/JMeterAMQP.jar $JMETER_HOME/libexec/lib/ext ls $JMETER_HOME/libexec/lib/ext -al
PROTIP: JMeter comes with extensions to work with protocols FTP, JDBC, JMS, LDAP, TCP, mail, MongoDB, etc.
Use Ivy to download file amqp-client-3.6.1.jar from the Maven Repo (dated Mar 01, 2016) from http://mvnrepository.com/artifact/com.rabbitmq/amqp-client/3.6.1 ??? into the $JMETER_HOME/lib folder created during JMeter install.
PROTIP: Books about RabbitMQ are listed at the bottom of the Maven web page.
On a Mac:
java -jar ivy.jar -dependency com.rabbitmq amqp-client 3.6.1 \ -retrieve "$JMETER_HOME/lab/[artifact](-[classifier]).[ext]"
Alternately, on Windows:
java -jar ivy.jar -dependency com.rabbitmq amqp-client 3.6.1 -retrieve "%JAVA_HOME%/lib/lib/[artifact](-[classifier]).[ext]"
Install RabbitMQ server under test
Based on http://www.rabbitmq.com/install-homebrew.html and video https://www.youtube.com/watch?v=8mFsh1cwlsA Feb 18, 2015 (on Yosemite) by YouTube DevOps celebrity Derek Bailey of http://watchmecode.net/
brew install rabbitmq
The response (at time of writing):
Updating Homebrew... ==> Auto-updated Homebrew! Updated 1 tap (caskroom/cask). No changes to formulae. ==> Downloading https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.2/rabbit Already downloaded: /Users/wilsonm/Library/Caches/Homebrew/rabbitmq-3.7.2.tar.xz ==> /usr/bin/unzip -qq -j /usr/local/Cellar/rabbitmq/3.7.2/plugins/rabbitmq_mana ==> Caveats Management Plugin enabled by default at http://localhost:15672 Bash completion has been installed to: /usr/local/etc/bash_completion.d To have launchd start rabbitmq now and restart at login: brew services start rabbitmq Or, if you don't want/need a background service you can just run: rabbitmq-server ==> Summary 🍺 /usr/local/Cellar/rabbitmq/3.7.2: 232 files, 12.6MB, built in 2 seconds
Put the executable within the PATH so it can be executed from any folder: https://rabbitmq.com/install-homebrew.htm
Do this permanently to your .bash_profile or .profile file.
Startup service under test
PROTIP: Start up the server in the background so the script can continue doing other things.
Use the nohup to bypass the HUP (hung up) signal that would otherwise cause a shutdown:
nohup rabbitmq-server &>/dev/null &
The response is the process number assigned, such as:
PROTIP: The &</dev/null prevents nohup from automatically creating a nohup.out file which would contain output from the rabbitmq-server command, such as:
## ## ## ## RabbitMQ 3.7.2. Copyright (C) 2007-2017 Pivotal Software, Inc. ########## Licensed under the MPL. See http://www.rabbitmq.com/ ###### ## ########## Logs: /email@example.com /usr/local/var/log/rabbitmq/rabbit@localhost_upgrade.log Starting broker... completed with 6 plugins.
PROTIP: The “&” ampersand at the end of the command
Stop background service
List the background jobs running:
+ Exit 1 nohup rabbitmq-server >&/dev/null
WARNING: Be sure to remember to stop this service when it’s not needed.
To remove all jobs in the background:
NOTE: Alternatively, start up the server every reboot using brew:
brew services start rabbitmq
==> Tapping homebrew/services Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-services'... remote: Counting objects: 14, done. remote: Compressing objects: 100% (10/10), done. Unpacking objects: 100% (14/14), done. remote: Total 14 (delta 0), reused 9 (delta 0), pack-reused 0 Checking connectivity... done. Tapped 0 formulae (42 files, 55.2KB) ==> Successfully started `rabbitmq` (label: homebrew.mxcl.rabbitmq)
Such would create processes listed by the ps command and killed by the pkill or pskill command.
PROTIP: Run the automated install script runs a “headless” JMeter instance since humans are not involved during script execution. Plus, the memory taken to display a GUI is saved for testing work.
When running headless, parameters are used.
Get a list of parameters recognized by jmeter:
The response has the version at the right edge (3.1 at time of writing):
Writing log file to: /Users/mac/jmeter.log _ ____ _ ____ _ _ _____ _ __ __ _____ _____ _____ ____ / \ | _ \ / \ / ___| | | | ____| | | \/ | ____|_ _| ____| _ \ / _ \ | |_) / _ \| | | |_| | _| _ | | |\/| | _| | | | _| | |_) | / ___ \| __/ ___ \ |___| _ | |___ | |_| | | | | |___ | | | |___| _ < /_/ \_\_| /_/ \_\____|_| |_|_____| \___/|_| |_|_____| |_| |_____|_| \_\ 3.1 r1770033 Copyright (c) 1999-2016 The Apache Software Foundation --? print command line options and exit -h, --help print usage information and exit -v, --version print the version information and exit -p, --propfile <argument> the jmeter property file to use -q, --addprop <argument> additional JMeter property file(s) -t, --testfile <argument> the jmeter test(.jmx) file to run -l, --logfile <argument> the file to log samples to -j, --jmeterlogfile <argument> jmeter run log file (jmeter.log) -n, --nongui run JMeter in nongui mode -s, --server run the JMeter server -H, --proxyHost <argument> Set a proxy server for JMeter to use -P, --proxyPort <argument> Set proxy server port for JMeter to use -N, --nonProxyHosts <argument> Set nonproxy host list (e.g. *.apache.org|localhost) -u, --username <argument> Set username for proxy server that JMeter is to use -a, --password <argument> Set password for proxy server that JMeter is to use -J, --jmeterproperty <argument>=
Define additional JMeter properties -G, --globalproperty <argument>=<value> Define Global properties (sent to servers) e.g. -Gport=123 or -Gglobal.properties -D, --systemproperty <argument>=<value> Define additional system properties -S, --systemPropertyFile <argument> additional system property file(s) -L, --loglevel <argument>=<value> [category=]level e.g. jorphan=INFO or jmeter.util=DEBUG -r, --runremote Start remote servers (as defined in remote_hosts) -R, --remotestart <argument> Start these remote servers (overrides remote_hosts) -d, --homedir <argument> the jmeter home directory to use -X, --remoteexit Exit the remote servers at end of test (non-GUI) -g, --reportonly <argument> generate report dashboard only, from a test results file -e, --reportatendofloadtests generate report dashboard after load test -o, --reportoutputfolder <argument> output folder for report dashboard </pre> To prepare Test plan in JMeter
Right-click Test Plan and go to Add->Thread(Users)->Thread Group. Give a name to Thread Group
A “Test Plan” is a container for “elements” which specifies the parameters for test runs.
Each “Thread Group” simulates what LoadRunner calls an individual virtual user.
Each “thread” is a unit of work that can be simultaneous or sequentially executed. (JMeter itself is multi-threaded).
Within the folder. run the jmeter GUI without any parameters:
This is returned while the Workbench GUI appears:
================================================================================ Don't use GUI mode for load testing, only for Test creation and Test debugging ! For load testing, use NON GUI Mode: jmeter -n -t [jmx file] -l [results file] -e -o [Path to output folder] & adapt Java Heap to your test requirements: Modify HEAP="-Xms512m -Xmx512m" in the JMeter batch file ================================================================================
PROTIP: JMeter should be invoked with more than the default amount of memory by adding paramenters to the HEAP environment variable.
Manually, switch to an internet browser to see the GUI:
open http://localhost:15672 curl --user guest:guest http://localhost:15672 -v
The default username and password are “guest” and “guest”.
PROTIP: The run.xml file in this repo has been edited to reference the above URL.
Sign up for Blazemeter’s Slack channel on JMeter https://info.blazemeter.com/slack-jmeter-lp-0
We have many channels and you’re always welcome to create your own. Here are 5 we recommend:
- &#_questions_answers - A place to ask and answer JMeter questions
- &#blog_posts - Share your JMeter blog posts here
- &#plugins - Get and share info about JMeter’s plugins to customize your testing scripts
- &#community_projects - A place to meet, plan and work together on JMeter load testing projects
- &#meetups - Learn and share when there are JMeter meetups in your area.
Videos on YouTube
Raghav Pal (since Jan 2, 2016) has an excellent JMeter Beginner Tutorial in his Automation Step by Step channel (supported by ads):
- How to install Jmeter [6:54] Jun 30, 2016
- How to create first Jmeter test [16:21] Jul 1, 2016
- How to use assertions [18:25] Jul 6, 2016
- How to use Listeners [18:53] Jul 8, 2016
- How to record a UI (Web) test [13:28] Jul 9, 2016
- How to create a Database Test Plan [10:13] Jul 9, 2016
- How to run jmeter from Command Line (non GUI mode) [11:32] Jul 10, 2016
- How to test FTP upload and download [12:56] Jul 24, 2016
- Testing Web Services API [20:32] Jul 31, 2016
- How to create assertions for JDBC (Database) Test Plan [9:45] Aug 2, 2016
- How to create HTML Dashboard Reports from command line [20:09] Aug 4, 2016
- How to use Plugins Manager [7:23] Aug 6, 2016
- How to read data from csv file (Parameterisation) [14:47] Aug 11, 2016
- Functions and Variables [13:57] Aug 13, 2016
- How to setup realistic performance test-PACING [11:02] Aug 28, 2016
- TIMERS (How to add Think Time) [11:13] Aug 29, 2016
- How to parameterize FTP test [8:23] Sep 4, 2016
- How to run Scheduled + Sequential execution [13:48] Sep 14, 2016
- Correlation (with Regular Expression Extractor) [12:30] Jan 15, 2017
- How to use TEMPLATES [7:13] Apr 11, 2017
- How to use Test Script Recorder [9:23] Apr 12, 2017
- How to test File Upload  Apr 14, 2017
- How to test File Download [6:25] Apr 14, 2017
- How to DEBUG [8:56] Apr 16, 2017
- How to record login test [8:14] Sep 11, 2017