Stress/Load-Testing of Asynchronous HTTP/REST Services with JMeter

Although I have been using JMeter for stress- and load-testing of web applications a good few times it took us a while to figure out how to test asynchronous HTTP/REST based services with the tool. With us I mean a fellow programmer – Holger Staudacher, I have the honor to work with currently on a project – and my humble self.

While Holger developed restfuse based on the experience of doing functional and integration tests for the project mentioned above, we decided to use JMeter for stress- and load-testing. The main service of the software under test processes a data structure that is uploaded to a certain URL. If the upload process was successful an URL pointing to a resource containing the processing result is returned. The resulting resource is not available immediately – processing takes a while. So polling is used to retrieve the resource once it is available1.

Our goal was to measure the time it takes to upload the data structure, process it and download the result resource in one test run. Running such a test with multiple users concurrently should give us a fair impression of the throughput capabilities of the system. Does not sound too complicated, but…

…our first approach writing a test plan for the scenario described in the previous paragraph using the on-board capabilities of JMeter did not work out very well. Neither was the plan comprehendible nor – and that was worse – made the measurement results any sense. In particular clamping the upload request and the polling loops together with a transaction controller seemed to have some unexpected side effects with timers. So after a while of additional Google research I stumbled across the JavaSamplerClient API, which I did not know before.

There is an entry at that describes how to extend the AbstractJavaSamplerClient – an implementation of JavaSamplerClient – and use it within JMeter. So this was the way to solve our problem. We created an extension of AbstractJavaSamplerClient overriding runTest(JavaSamplerContext). Within that method we use HttpClient to perform the upload and poll requests. Once the processing result is successfully retrieved by a poll request all the header and content information is stored in an instance of SampleResult. The latter is returned by the overridden test sampler method for further processing by JMeter – quite straight forward2.

Once you have created a jar that contains a custom JavaSampleClient and put this into the lib/ext/ folder below your JMeter installation directory you can add a Sampler type Java Request to your Thread Group. This allows you to select and configure a custom sampler as shown in the picture below:

Using the the JavaSamplerClient made our test plan very simple and allowed us to use the common JMeter result measurement functionality as shown below examplary with the Graph Results view:

And of course the measurement results are now reasonable…

Since we had to fumble quite a while to get this done I thought our solution might be of interest for other people, too – which was the reason to write this post. But it would be also interesting to hear from you if there are easier solutions we did not notice. So feel welcome to provide feedback

  1. We started using WebHooks but our customer had problems to convince the IT admins to open up the firewall…
  2. For the sake of a reasonble length of this post I skip any description of how to deal with unsuccessful requests – but most of our implementation work had to be done in that area…

Reference: Stress/Load-Testing of Asynchronous HTTP/REST Services with JMeter from our JCG partner Frank Appel at the Code Affine blog.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply

8 − = three

Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books