I’ve recently run STOMP benchmarks against the lastest releases of the 4 most feature packed STOMP servers:
- Apache ActiveMQ 5.5.1
- Apache ActiveMQ Apollo 1.0 Beta 6 (an ActiveMQ Subproject)
- HornetQ 2.2.5
- RabbitMQ 2.7.0
STOMP is an asynchronous messaging protocol with design roots are based on HTTP protocol. It’s simplicity has made the protocol tremendously popular since it reduces the complexity of integrating different platforms and languages. There are a multitude of client libraries for your language of choice to interface with STOMP servers.
The benchmark focuses on finding the maximum producer and consumer throughput for a variety of messaging scenarios. For example, it benchmarks a combination of all the following scenario options:
- Queues or Topics
- 1, 5, or 10 Producers
- 1, 5, or 10 Consumers
- 1, 5, or 10 Destinations
- 20 byte, 1k, or 256k message bodys
The benchmark warms up each scenario for 3 seconds. Then for 15 seconds it samples the total number of messages that were produced/consumed every second. Finally, the destination gets drained of any messages before benchmarking the next scenario. The benchmark generates a little HTML report with a graph for each scenario run where it displays messaging rate for each of the servers over the 15 second sampling interval.
I’ve run the benchmarks on a couple if different machines and I’ve posted the results at: http://hiramchirino.com/stomp-benchmark/
Since anyone can get access to an EC2 instance to reproduce those results, the rest of this article will focus on the results of the obtained on the EC2 High-CPU Extra Large Instance. If you want to reproduce, just spin up a new Amazon Linux 64 bit AMI and then run the following commands in it:
sudo yum install -y screen curl https://nodeload.github.com/chirino/stomp-benchmark/tarball/master | tar -zxv mv chirino-stomp-benchmark-* stomp-benchmark screen ./stomp-benchmark/bin/benchmark-all
Note: RabbitMQ 2.7.0 sometimes dies midway through the benchmark. It seems RabbitMQ does not enforce very strict flow control and you can get into situations where it runs out of memory if you place too much load on it. It seems that crash becomes more likely as you increase the core speed of the cpu or reduce the amount of physical memory on the box. Luckily, the RabbitMQ folks are aware of the issue and hopefully will fix it by the next release.
The ‘Throughput to an Unsubscribed Topic’ benchmarking scenario is interesting to just get a idea/base line what the fastest possible rate a producer can send to server. Since there are not attached consumers, the broker should be doing very little work since it’s just dropping all the messages that get sent to it.
The Queue Load/Unload scenarios a very important to look at if your application uses queues. You often times run into situations where messages start accumulating in a queue with either no consumers or with not enough consumers to keep up with the producer load. This benchmark first runs a producer for 30 seconds enqueuing non-persistant messages and then runs a producer enqueuing persistant messages for 30 seconds. Finally, it runs a consumer to dequeue the messages for 30 seconds. An interesting observation in this scenario is that Apollo was the only sever which could dequeue at around the same maximum enqueue rates which is important if you ever want your consumers to catch up with fast producers.
The Fan In/Out Load Scenarios help you look at cases where you have either multiple producers or multiple consumers running against a single destination. It helps you see how performance will be affects as you scale up the producers and consumers. You should follow the “10 Producers” columns and “10 Consumers” rows to really get a sense of which servers do well as the you increase the number of clients on a single destination.
The Partitioned Load Scenarios look at how well the server scales as you start to increase load on multiple destinations at different message sizes.
I’ve tried to make the benchmark as fair as possible to all the contenders, all the source code to the benchmark is available on github. Please open an issue or send me pull request if you think of ways to improve it!