Thursday, 8 November 2012

JBoss HornetQ for Kids, Parents and Grandparents – Chapter 1


It’s now almost 4 years that I’m working with HornetQ and I think it’s time to share part of what I learnt so far.

The main purpose of this post is not to rewrite the official documentation, but it’s to clarify, in simple ways, the concepts we use most here in PaddyPower .

What is HornetQ


HornetQ is a JMS implementation. JMS is a message oriented middle-ware API to exchange information between producers and consumers in an asynchronous way.
HornetQ is one of the numerous framework out there that implement the JMS API.

Configuration


All the HornetQ configuration we care about is in 1 folder. How beautiful is that?! The folder is hornetq (or hornetq.sar dipending on the jboss version you are using) and you can find it in your jboss profile deploy folder.
In this folder we have up to 7 xml configuration files. We really care only about 2:
hornetq-jms.xml and hornetq-configuration.xml.

hornetq-jms.xml

This is where you want to define your JNDI names for queues, topics and connection factories.
By default all the Connection factories, the dead letter and the expiry Queue are already configured.
What you need to add is only the queues or topics that your application needs to use.
For example:
<queue name="phaseQueueFromEngine">
     <entry name="/queue/phaseQueueFromEngine"/>
</queue>
the entry name is the JNDI name used by your producer and consumer to discover the queue.

hornetq-configuration.xml

This is where you want to define acceptors, connectors, bridges and other cool stuff.

Understanding Connectors & Acceptors
Ok, this can be tricky, so I’ll try to be simple and essential.
HornetQ run in a server (JBoss for example) or as standalone application.
In any of the above cases, HornetQ works by communicating with his own server, the HornetQ server.
In order to communicate with it, we have to tell how we connect to and what we accept as connection.
  • Acceptors define which type of connection are accepted by the HornetQ Server.
  • Connectors define how to connect to the HornetQ server.
Luckily, only 2 kind of connectors and acceptors are possible, in-vm and netty.
in-vm is used when the producer and the consumer lives in the same virtual machine.
Example:
<acceptor name="in-vm">
        <factory-class>org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory</factory-class>
</acceptor>
<connector name="in-vm">
       <factory-class>org.hornetq.core.remoting.impl.invm.InVMConnectorFactory</factory-class>
</connector>
netty must be used when the producer and the consumer lives in different virtual machines.
Example:
Producer/Consumer in the same machine:
<acceptor name="netty">
         <factory-class>org.hornetq.integration.transports.netty.NettyAcceptorFactory</factory-class>
         <param key="host"  value="${host:localhost}"/>
         <param key="port"  value="${port:5445}"/>
      </acceptor>
<connector name=”netty”>
<factory-class>org.hornetq.integration.transports.netty.NettyConnectorFactory</factory-class>
<param key=”host”  value=”${host:localhost}”/>
<param key=”port”  value=”${port:5445}”/>
</connector>
Producer/Consumer in different machines:
Consumer Box
<acceptor name=”netty-external-acceptor”>
<factory-class>org.hornetq.integration.transports.netty.NettyAcceptorFactory</factory-class>
<param key=”host”  value=”172.x.x.62″/>
<param key=”port”  value=”5445″/>
</acceptor>
Producer Box
<connector name="remote-engine-connector">
         <factory-class> org.hornetq.integration.transports.netty.NettyConnectorFactory</factory-class>
         <param key="host" value="172.x.x.62"/>
         <param key="port" value="5445"/>
      </connector>
So far so good.
Pay attention when you configure acceptors and connectors because in order to communicate properly they have to be the same kind with the same host and port.
netty acceptor with netty connector (same host and port ) GOOD
in-vm acceptor with in-vm connector GOOD
in-vm acceptor with netty connector BAD
netty acceptor port 5445 with netty connector 5446 BAD
netty acceptor host 172.x.x.60 with netty connector 172.x.x.62 BAD
Understanding Bridges
Another feature I widely used is the bridge.
If you have a producer living in the box 172.x.x.60 and the consumer sitting in the box 172.x.x.62 you need to connect them and you do this configuring a bridge in our beloved configuration file hornetq-configuration.xml
Example :
<bridge name=”from60to62Bridge”>
<queue-name>jms.queue.phaseQueueToEngine</queue-name>
<forwarding-address>jms.queue.phaseQueueFromInput</forwarding-address>
<reconnect-attempts>-1</reconnect-attempts>
<connector-ref connector-name=”remote-engine-connector”/>
</bridge>
Yes, you use the connector to specify where to connect to the other hornetQ server. Easy!
I hope this will clarify a couple of aspects and it will help to understand better the sometime scary Hornetq configuration.
Coming soon.. HornetQ for Kids, Parents and Grandparents – Chapter 2: the magic of address-settings

2 comments:

  1. great post!

    if you like you can evaluate my book on hornetq

    http://www.amazon.com/dp/1849518408/?tag=packtpubli-20

    ReplyDelete
  2. Thanks Piero, Your book looks very interesting, I will read it for sure.

    ReplyDelete