ActiveMQ HTTP transport connector load balanced with HAProxy

ActiveMQ HTTP transport connector load balanced with HAProxy

First post in a series dedicated to the message broker ActiveMQ. In these lines, we will discuss the specificities of the cloud and in particular Active MQ HTTP / HAProxy. Have a good reading!

Adaptation of the article:" ActiveMQ HTTP transport connector load balanced with HAProxy» of blog Nanthrax written by Jean-baptiste Onofré (Technical Advisor)

yupiik-apache-activemq

If you are using ActiveMQ, you probably use the default tcp transport connector configured in the conf/activemq.xml :

<transportConnectors>
    <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>

ActiveMQ also provides other transport connectors for specific protocols (amqp, mqtt, stompor particular transports.

In particular, it supports a very practical transport connector to pass through firewalls: the transport connector http (and extended from http like https, etc.).

It is therefore possible to balance the load of HTTP connections. However, we will not be able to balance the messages: we need a network of brokers for this purpose, (see other articles of the blog about this subject).

However, the HTTP transport is based on the openwire protocol. So, it’s not just a HTTP request to send a message: the client has to send several HTTP requests to establish the connection.

Basically, the client first does a HEAD HTTP request (to get the option of the transport connector, like if the Gzip compression is supported or not), then it sends a series of GET HTTP requests. For each GET request, the ActiveMQ broker will reply the openwire protocol version, the broker topology, etc.

The correlation between each HTTP request is based on a HTTP header: the clientID. The ActiveMQ HTTP connector maintains a map of clients, with their current state, based on the clientID.

If we want to balance the HTTP requests, we can’t use a simple round-robin on each request. Instead we have to balance either:

  1. the client IP address : all requests coming for a IP address will be routed to the same ActiveMQ broker
  2. The header clientID : all requests coming with the same clientID header will be routed to the same ActiveMQ broker

We are going to use the clientID HTTP header.

Imagine if you had two ActiveMQ brokers. Each broker exposes an HTTP transport connector. This means that you have:

  • amq1 is running on 192.168.134.2, with the HTTP transport connector bound to 8282 for instance
  • amq2 is running on 192.168.134.3, with the HTTP transport connector bound to 8282 for instance

We can “façade” those two ActiveMQ brokers with HAProxy. The HAProxy configuration looks like:

listen balance
  bind *:80
  mode http
  balance hdr(clientID)
  server amq1 192.168.134.2:8282
  server amq2 192.168.134.3:8282

The important configuration is the balanceone, where you can see the use of clientID header for the balancing affinity.

In the next article, we will see how to use Hazelcast to address clientID affinity.

Blocked in your roadmaps?

Would you like to train your teams?

en_GBEnglish (UK)
fr_FRFrançais en_GBEnglish (UK)