ActiveMQ HTTP transport connector load balanced with HAProxy

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 some particular protocols (amqp, mqtt, stomp) or particular transports.

Especially, it supports a very convenient transport connector to go through firewalls: the http transport connector (and extended from http like https, etc.

It means that it’s possible to load balance the HTTP connections. We won’t be able to balance the messages (we need a network of brokers for that, see previous blog posts about that.

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 clientID header (all request coming with the same clientID header will be routed to the same ActiveMQ broker)

We are going to use the later (the clientID HTTP header) with HAProxy.

So, imagine, you have two ActiveMQ brokers. Each broker exposes a HTTP transport connector. It means you have the following:

  • 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 balance one, where you can see the use of clientID header for the balancing affinity.

That’s the first post of a series related to ActiveMQ “classic” for the cloud. In the next one, I will show how to use Hazelcast for deal with clientID affinity.

You May Also Like

About the Author: jbonofre

ASF Member, PMC for Apache Karaf, PMC for Apache ServiceMix, PMC for Apache Archiva, PMC for Apache Felix, PMC for Apache Camel, PMC for Apache Syncope, PMC for Apache Beam, PMC for Apache CarbonData, PMC for Apache Bahir, PMC for Apache Brooklyn, PMC for Apache Falcon, PMC for Apache Guacamole, PMC for Apache Lens, Committer for Apache ActiveMQ and much more ! Twitter: jbonofre IRC: jbonofre on #servicemix,#karaf,#camel,#cxf on Freenode