Getting Started with Messages for RabbitMQ

10 min read

Covering the basics about the differences between Compose for RabbitMQ and Messages for RabbitMQ.

So, you're taking a look at Messages for RabbitMQ. You might be coming from a similar RabbitMQ service like Compose, but you want to know what to expect when you've made the switch. 

In this blog post, we'll cover some of the differences between Compose for RabbitMQ and Messages for RabbitMQ and show you how to switch over with the right configuration from the start.

Comparison: IBM Compose for RabbitMQ vs. Messages for RabbitMQ

Comparison: IBM Compose for RabbitMQ vs. Messages for RabbitMQ

* Must contact support for availability

Scaling

If you look at the differences between Compose for RabbitMQ and Messages for RabbitMQ, the elephant in the room is scaling. Compose autoscales RabbitMQ for you. This means that as your workload increases, your RabbitMQ disk and RAM will increase together—they have a 1:1 relationship. Your deployment's RAM is checked every minute, so if RAM increases, more units of RAM will be added.

mq1

The caveat here, however, is that if your RAM increases, it will remain increased until you've manually scaled it down. Therefore, you'll need to watch your deployment in order to mitigate costs. Also note that with Compose, your resources are not unlimited. Once you hit the threshold of 32GB of RAM and disk space, you've run out.

For more granularity and higher resource limits, you'll need to deploy Messages for RabbitMQ. With Messages for RabbitMQ, you start off with 1GB RAM and disk but you control both RAM and disk independently in the message queue settings, allowing you to scale to what you need. These settings can be controlled using the IBM Cloud UI or through the IBM Cloud API. 

mq2

Since Messages for RabbitMQ doesn't autoscale, it's imperative to monitor your RAM and disk usage. This can be done via the RabbitMQ HTTP API or right from the RabbitMQ administration panel. This is discussed below. 

It's very important to note that for disk, once you've scaled up your deployment, you cannot scale down. This is the nature of using block storage for IBM Cloud Databases, and it applies to every IBM Cloud Database offering. 

How much disk and RAM is good enough?

This is a question we get quite a bit. If you're coming from Compose, you need to know that the amount of RAM and disk you had on your deployment is quite different from Messages for RabbitMQ. On Compose, we use SSDs on bare metal with SoftLayer; however, Messages for RabbitMQ uses the endurance tier of IBM Cloud Block Storage.

Block Storage calculations are different in that you get 10 IOPS (input/output operations per second) per 1GB allocated. Overall, IOPS affects message throughput and storage operations, which could lead to a disk falling behind when trying to get the space back after messages have been consumed. This would lead to the publisher throttling until all your activity slows down to a screeching halt. Therefore, increase the number of IOPS available by increasing the disk space to avoid get a sneaky disk error right from the start. 

On the other hand, RAM is another issue. On Messages for RabbitMQ, you can scale the RAM up and down. Watch your deployment using any of the IBM monitoring tools. In general, if you anticipate a spike in your usage or your memory consumption is really high, scale up your deployment's RAM. If you're coming from Compose, you should anticipate scaling up your RAM. Recent Erlang versions that newer versions of RabbitMQ use have less conservative memory usage. Thus, anticipate a higher memory watermark than Compose.

Essentially, you want to scale up both disk and RAM to acceptable levels in order to avoid performance issues, and also to avoid disk and memory alarms, which we'll look at now.

RAM and disk alerts

RabbitMQ has memory and disk alarms that will alert you when you're about to reach your deployment's RAM and disk capacity. Prior to reaching your deployment's memory and disk capacity, RabbitMQ will trigger an alarm that will block connections that publish messages. 

For RAM, an alarm will be raised when you use more than 40% of the allocated memory. For disk, an alarm will trigger once you've reached 80% of your allocated space. In both cases, connections will be blocked and you'll have to clear the alarms before the connections to publish messages are restored. 

RabbitMQ disk alarms are cluster-wide, so if an alarm is triggered on one node then, consequently, all nodes will be blocked until you've cleared the alarm. You can read more about RabbitMQ alarms in their documentation for RAM and disk.

One way to monitor your usage and receive notifications if an alarm is triggered is to listen for block notifications through a client. When RabbitMQ is low on RAM or disk, a connection.blocked notification is sent to publishing connections. However, if your deployment is low on RAM and disk, you'll only get one notification. 

For instance, if your deployment gives you a connection.blocked notification, you'll need to check first if the RAM or disk alarm has been triggered. Once you've determined whether to scale up RAM, disk, or both and completed the scaling process, then another notification will be sent—connection.unblocked—and messages will resume publishing.

Monitoring for blocked connections, in addition to your RAM and disk consumption, can be done through IBM Cloud LogDNA or through the IBM Cloud Monitoring service. 

You could also see whether memory or disk alarms were activated using the RabbitMQ HTTP API. Access the /api/nodes endpoints, and look for mem_alarm and disk_free_alarm in the GET response. false indicates that an alarm was not triggered.

curl --cacert </path/to/ca_certificate> -XGET https://<username>:<password>@<aaa.databases.appdomain.cloud>:<port>/api/nodes


{
        ...
        "mem_alarm": false,
        ...
          "disk_free_alarm": false,
          ...
}

For additional checks related to memory alarms, you can gather information related to a single node's memory using the RabbitMQ HTTP API endpoint GET /api/nodes/{node}/memory.

Monitoring RAM and disk

In order to anticipate whether you're going to trigger an alarm, it's always good to monitor your deployment. RabbitMQ's HTTP API comes with several endpoints that are accessible to gather statistics about your deployment. These endpoints are are broken down by cluster, node, and queue. For the curious, RabbitMQ has an entire section of documentation that discusses monitoring.

Some of the metrics endpoints that you may find useful are as follows:

  • Cluster: GET /api/overview
  • Node: GET /api/nodes/{node} for one node, or for all members GET /api/nodes
  • Queues: GET /api/queues/{vhost}/{queue_name}

When monitoring RAM, note that memory usage spikes are bound to happen. A spike can occur during resyncs when we restart or delete nodes when updating the system. Memory usage increases in order to synchronize the data from existing nodes to a new node. 

Coming from Compose, you didn't experience this because you didn't handle the memory; however, with Messages for RabbitMQ, you need to account for this so you don't run the risk of a memory alarm or running out of memory. This is one reason why you should allocate more RAM to your Messages for RabbitMQ deployment than what you previously had on Compose. 

Standard health checks

When monitoring, you also should run health checks on your systems to ensure that it's running appropriately, especially if you start to see things slow down. The RabbitMQ HTTP API comes with health check endpoints that allow you to monitor the state of individual nodes and provide some advice on the steps you can take if you want to really dig into health checking your deployment.

  • All Nodes: GET /api/healthcheck/node
  • Single Node: GET /api/healthcheck/node/

For smaller deployments, the health check shouldn't take very long to give you a response. However, with larger deployments, it could take some time for results to appear.  

Now, let's talk about using RabbitMQ and the differences between Compose and IBM Cloud Messages.

Accessing RabbitMQ administrator UI

There are a couple differences between Compose for RabbitMQ and Messages for RabbitMQ when gaining access to the RabbitMQ administrator UI. To quickly connect to the Compose for RabbitMQ UI, select the Data Browser button at the top of your Compose for RabbitMQ management console in IBM Cloud. 

To quickly connect to the Compose for RabbitMQ UI, select the Data Browser button at the top of your Compose for RabbitMQ management console in IBM Cloud. 

You'll have to use the administrator username and password for your deployment to gain access. In order to do that, you'll need to reset the password for the admin user via the Settings tab for both Messages for RabbitMQ and Compose.

For Messages for RabbitMQ, quick access to the RabbitMQ administrator UI is found in the Public Endpoints panel. Click the blue Launch button next to the connection URI.

For ICM RabbitMQ, quick access to the RabbitMQ administrator UI is found in the Public Endpoints panel. Click the blue Launch button next to the connection URI.

Again, you'll have to use the administrator username and password for your deployment to log in.

Note that if your Messages for RabbitMQ uses private endpoints, you will not be able to access the RabbitMQ administrator UI from your web browser.

User management

When provisioning Messages for RabbitMQ, you're given two users: admin and ibm. Both are administrators but admin is the only one you have access to. ibm is reserved for maintenance operations. 

mq5

With Compose, you're given the admin and guest users.

mq6

If you subsequently want to add users to Messages for RabbitMQ, do so from the Service Credentials panel in your deployment's management window:

If you subsequently want to add users to ICM RabbitMQ, do so from the Service Credentials panel in your deployment's management window:

Users set up here will automatically be given the monitoring tag in your Messages for RabbitMQ deployment:

Users set up here will automatically be given the monitoring tag in your ICM RabbitMQ deployment:

However, if you want to create users using the management UI or from the RabbitMQ HTTP API, you can assign any tag that's available.

Access to virtual hosts

RabbitMQ uses virtual hosts, or a logical grouping of connections, exchanges, queues, bindings, user permissions, and policies. Think of these as isolated environments. When a client makes a connection to a specific vhost, you're essentially making a connection to the collection of resources within the virtual host. 

Compose for RabbitMQ comes with one virtual host that starts with the cluster name deployment, like bmix-.... On Compose, only AMPQ 0.9.1 is supported. 

mq9.1

Messages for RabbitMQ only comes with a single virtual host— \. You can create other virtual hosts via the terminal or RabbitMQ HTTP API. However, unlike Compose, Messages for RabbitMQ supports AMPQ 0.9.1 and 1.0. 

mq10

Creating virtual hosts

Creating a virtual host using the RabbitMQ HTTP API is accomplished by giving a name to the new virtual host at the end of the /api/vhosts endpoint. In this example, we'll name the new virtual host new-host using the API endpoint along with our Messages for RabbitMQ credentials:

curl --cacert /path/to/ca_certificate -XPUT https://<username>:<password>@aaa.databases.appdomain.cloud:<port>/api/vhosts/new-host

The command will not give you a response that the new virtual host was created. So, you can either verify it from the RabbitMQ HTTP API:

curl --cacert /path/to/ca_certificate -XGET https://<username>:<password>@aaa.databases.appdomain.cloud:<port>/api/vhosts

Or, from the rabbitmqadmin tool:

rabbitmqadmin -U https://<username>:<password>@aaa.databases.appdomain.cloud:<port> -s --ssl-ca-cert-file=/path/to/ca_certificate list vhosts 

If you want to make a connection between queues and exchanges between different vhosts and continually move messages from one broker to another, use the RabbitMQ Shovel Plugin that's installed by default on Messages for RabbitMQ. The Shovel Plugin is only available with Messages for RabbitMQ and automatically moves messages for you from broker to broker. The plugin basically acts like a client that reads and writes messages from a source to a destination that you define using AMPQ 0.9.1 or AMPQ 1.0. 

More information about the Shovel Plugin can be found in the RabbitMQ documentation.

Virtual hosts and high availability

The default virtual host that comes with Compose for RabbitMQ, and ICM RabbitMQ deployments already have high availability configured for the default exchanges.

To configure high availability for new virtual hosts, you'll need to add a policy. You can add policies from the ICD RabbitMQ UI, rabbitmqadmin tool, or the RabbitMQ HTTP API. See the following documentation on the high availability parameters you have available.

Using the ICD RabbitMQ UI, simply click on the Admin tab, then click the Policies button on right-hand menu. 

Using the ICD RabbitMQ UI, simply click on the Admin tab, then click the Policies button on right-hand menu. 

Here, we set up a policy on our test1 virtual host and called it ha-test1. From there, we added high-availability mode on all exchanges and queues. High availability is only configured on the default virtual host that's provided. All subsequent virtual hosts that you create that need HA will need to be configured either from the RabbitMQ administrator dashboard, rabbitmqadmin tool, or using curl.

You can also create policies using the RabbitMQ HTTP API. Below is an example of the same policy we created using curl

curl --cacert /path/to/ca_certificate -XPUT https://<username>:<password>@aaa.databases.appdomain.cloud:<port>/api/policies/test1/ha-test1 \
-d '{"pattern": ".*", "definition": {"ha-mode": "all", "ha-sync-mode": "automatic"}, "priority": 0, "apply-to": "all"}'

Connection URI differences

When connecting to Compose for RabbitMQ, you're provided with two haproxy portals that are connected to three nodes. You'll use all of the URIs in your application code when making a connection to Compose. 

With Messages for RabbitMQ, you're provided with a single URI to connect, and this URI will reach out to three virtual IPs (VIP) that might change over time. In this case, when making a connection to RabbitMQ, you'll need to implement connection retry logic so that your application will attempt another connection if one VIP is down.

Let's cover the differences when connecting to Compose for RabbitMQ and Messages for RabbitMQ.

Connecting with SSL/TLS

Of course, when you connect to Compose for RabbitMQ and Messages for RabbitMQ, you're using a TLS-enabled connection. Both Compose and Messages for RabbitMQ support HTTPS and AMQPS connections, but STOMP and MQTT are an additional cost that must be added by support. However, ICM RabbitMQ has STOMP and MQTT available by default.

If you've been using Compose, your deployment will have a connection string with either composedb or dblayer in the URI. If your deployment has composedb, it's using a Let's Encrypt certificate. However, if you have dblayer in the connection string, you're using the CA certificate that we provided.

When moving over to Messages for RabbitMQ, the good news is that if you've been using a CA certificate already with Compose, then Messages for RabbitMQ also uses a CA certificate. However, if you haven't been using a CA certificate, you'll have to make some changes to your application's code.

Below is a basic example in Python that connects to Messages for RabbitMQ with the connection string and the self-signed certificate. We're connecting to Messages for RabbitMQ using the pika library along with retry, which will use the retry decorator to set up connection recovery if your connection briefly fails. The example below modifies the code here:

import pika
import ssl
from urllib.parse import urlparse


compose_rabbitmq_url = os.environ['ICM_RABBITMQ_URI']
parsed = urlparse(compose_rabbitmq_url)
context = ssl.create_default_context(
    cafile='<path/to/certificate>'
)
ssl_options = pika.SSLOptions(context, parsed.hostname)
credentials = pika.PlainCredentials(parsed.username, parsed.password)


parameters = pika.ConnectionParameters(
    host=parsed.hostname,
    port=parsed.port,
    credentials=credentials,
    ssl_options=ssl_options
)


@retry(pika.exceptions.AMQPConnectionError, delay=5, jitter=(1, 3))
def consume():
    print("Connecting ...")
    connection = pika.BlockingConnection(parameters)
    channel = connection.channel()
    channel.basic_qos(prefetch_count=1)
    channel.queue_declare('recovery-example', durable = False, auto_delete = True)
    channel.basic_consume('recovery-example', on_message)
    try:
        channel.start_consuming()
    except KeyboardInterrupt:
        channel.stop_consuming()
        connection.close()

Connection blips

Messages for RabbitMQ deployments are highly available. This means that we provide replication, fail-over, and high-availability features that protect RabbitMQ from infrastructure maintenance, upgrades, and failures on the system. 

Applications that are communicating over networks and cloud services are subject to transient connection failures. Therefore, you need to design your applications to be resilient and handle connection errors that caused a temporary loss in connectivity to Messages for RabbitMQ. Temporary losses might occur when regular updates or database maintenance occurs, which is all part of any normal cloud provider's operations. 

Therefore, your application must be designed to handle these temporary interruptions by handling failures and implement retry logic to recover from a temporary interruption. 

Summary

This article covers the basics about the differences of Compose for RabbitMQ and Messages for RabbitMQ. We covered scaling, disk and memory usage, alarms, users and vhosts, and connecting to RabbitMQ. 

These cover a lot of the questions that customers have when diving into Messages for RabbitMQ for the first time, especially if you're coming directly from Compose. If you have any more questions, please reach out to us in support, and we'll be happy to answer any questions you might have. 

Be the first to hear about news, product updates, and innovation from IBM Cloud