RabbitMQ clusters don't mirror queues by default. The queues are stored in the broker nodes connected to the clients that created them. Whenever such a node fails, all the queues and the messages stored within it aren't available.
If you have defined the queues as durable and the messages as persistent, it's possible to restore the node without losing data but this is not sufficient.
In fact, designing a highly available application can't be acceptable. There are many cases where the application must be able to survive the death of one component without interruption.
The ha-policies help to solve this problem. In this recipe, we will show you how to mirror a queue across all the nodes in the cluster.
In order to configure a mirror queue, there are two ways that can be used; that is, it can be configured using rabbitmqctl
or using the web management plugin (or its API). We will show both the ways in the following steps:
mirror-all
to the Name field, ^mirr.
to the Pattern field, and ha-mode
and all
to the Definition field.rabbitmqctl
:rabbitmqctl set_policy ha-all "^mirr." '{"ha-mode":"all"}'
mirr.q_connection_1_1
. (It's important that the prefix is mirr.
; you are free to call the queue as you prefer.)After creating the cluster (refer to step 1), you need to define the mirror queues' behavior using ha-policies
(refer to step 2).
The mirror-all
parameter is the policy name, and the ^mirr.
string is the regular expression pattern. We are instructing RabbitMQ to mirror all the queues that have names starting with mirr.
.
The last parameter is the mirroring mode. With ha-mode:all
, the queues are mirrored across all the nodes in the cluster using a master slave pattern (the slaves can be more than one). Whenever a queue matches the given pattern is created on one node, it is replicated on all the others, and whenever a client starts inserting messages in it, they are replicated across all the slaves.
For example, if we have three nodes, namely rabbit@rabbitmqc1
, rabbit@rabbitmqc2
, and rabbit@rabbitmqc3
, and we create a queue with the prefix mirr.
on the rabbitmqc1
node (the master for this queue), the queue will be replicated on the other two nodes (the slaves) as well. In order to check the queue's status, open the web management console and click on the Overview tab of the queue, as shown in the following screenshot:
If the rabbitmqc1
node is down or unavailable, a new master will be promoted for the queue. For example, if we shut it down by calling rabbitmqctl stop_app
, the rabbit@rabbitmqc3
node is promoted as the master for the mirr.q_connection_1_1
queue, as shown in the following screenshot:
When we restart rabbit@rabbitmqc1
, the queue is mirrored again. Thanks to the defined policy, it is configured as a slave and not promoted to a master as it was originally:
The cluster is fully mirrored again.
In this recipe we have seen how to quickly set up mirrored queues, but it's not enough to build a fully and highly available solution based on RabbitMQ. In fact, the RabbitMQ mirroring configuration lets the broker keep copies of the messages to avoid losing any message. But, it's important to properly handle the connections and the messages on the client side in order to take advantage of this.
In the next recipes, we will learn about the mirror queues in detail, tackling all these aspects.
At http://www.rabbitmq.com/ha.html, you can find all the details on RabbitMQ high availability.
For more details on policies, refer to http://www.rabbitmq.com/parameters.html#policies.