Migrating from RabbitMQ to Amazon MQ

Migrating from RabbitMQ to Amazon MQMore Info

This article is based on contributions from Jamie Carter, an AWS Solutions Architect.

UPDATE – As of November 4, 2020, Amazon MQ added support for RabbitMQ, allowing you to transition your existing RabbitMQ message brokers to AWS without the need for extensive code rewrites. You can discover how to easily migrate your applications by checking out this updated blog post.

Message brokers play a crucial role in enterprise architectures by helping manage workload queues and disseminating messages to multiple subscribers. Many AWS customers currently utilize RabbitMQ and are interested in switching to a managed service to alleviate the operational burden of maintaining their own message broker.

Amazon MQ is a fully managed message broker service for Apache ActiveMQ, simplifying the process of operating and scaling message brokers in the cloud. It is compatible with your existing workloads that utilize standard protocols like OpenWire, AMQP, MQTT, and Stomp (all secured with SSL). Amazon MQ automatically provisions infrastructure configured as either a single-instance broker or as an active/standby broker to ensure high availability.

In this article, I will guide you through launching a new Amazon MQ instance. I will also present example Java code for migrating from a RabbitMQ to an Amazon MQ message broker using clients for ActiveMQ, Apache Qpid JMS, and Spring JmsTemplates. Additionally, I will discuss best practices for Amazon MQ and the changes required when moving from RabbitMQ to support Publish/Subscribe message patterns.

Getting Started with Amazon MQ

To begin, navigate to the Amazon MQ console. Enter a broker name and proceed to the next step.

Launch a new Amazon MQ instance by selecting the mq.t2.micro instance type and the Single-instance broker deployment mode. Then, create a username and password before clicking on “Create broker.”

After a few minutes, the status of your instance will change from “Creation in progress” to “Running.” You can view the Details page of your broker to access connection information, including a link to the ActiveMQ web console where you can monitor the status of your instance queues, etc. In the following code examples, you will be using the OpenWire and AMQP endpoints.

To access your broker, ensure that one of your security groups allows inbound traffic. For more detailed instructions, refer to the link in the blue box in the Connections section.

Now that your Amazon MQ broker is up and running, let’s dive into some code!

Dependencies

The following code examples require various libraries to demonstrate RabbitMQ, ActiveMQ, Qpid, Spring JMS templates, and connection pooling. Below is a comprehensive list of dependencies in a single Maven pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>MyGroup</groupId>
    <artifactId>MyArtifact</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
        <!-- RabbitMQ -->
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.1.2</version>
        </dependency>
        <!-- Apache Connection Pooling -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-pool</artifactId>
            <version>5.15.0</version>
        </dependency>
        <!-- Apache ActiveMQ -->
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-client</artifactId>
            <version>5.15.0</version>
        </dependency>
        <!-- Apache QPid -->
        <dependency>
            <groupId>org.apache.qpid</groupId>
            <artifactId>qpid-client</artifactId>
            <version>6.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.qpid</groupId>
            <artifactId>qpid-jms-client</artifactId>
            <version>0.29.0</version>
        </dependency>
        <!-- Spring JmsTemplate -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
            <version>5.0.3.RELEASE</version>
        </dependency>
        <!-- Logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
    </dependencies>
</project>

RabbitMQ

Here’s a sample code snippet that demonstrates how to send and receive a message using a RabbitMQ queue. Note that the installation and configuration of RabbitMQ are not covered in this article. For instructions on downloading and installing RabbitMQ, refer to Downloading and Installing RabbitMQ.

RabbitMQ operates with the AMQP 0-9-1 protocol by default, and it also supports AMQP 1.0 through a plugin. The RabbitMQ examples provided here utilize the AMQP 0-9 protocol.

RabbitMQ Queue Example

To start, here’s some sample code for sending and receiving a message in RabbitMQ via a queue:

import java.io.IOException;
import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.GetResponse;

public class RabbitMQExample {

    private static final boolean ACKNOWLEDGE_MODE = true;

    // Externalize and configure the Endpoint, Username, Password, and Queue via environment variables or dependency injection.
    private static final String ENDPOINT;
    private static final String USERNAME;
    private static final String PASSWORD;
    private static final String QUEUE = "MyQueue";

    public static void main(String[] args) throws KeyManagementException, NoSuchAlgorithmException, URISyntaxException, IOException, TimeoutException {
        // Create a connection factory.
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setUri(ENDPOINT);

        // Set the username and password.
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);

        // Establish a connection for the producer.
        Connection producerConnection = connectionFactory.newConnection();

        // Create a channel for the producer.
        Channel producerChannel = producerConnection.createChannel();

        // Declare a queue named "MyQueue".
        producerChannel.queueDeclare(QUEUE, false, false, false, null);

        // Create a message.
        String text = "Hello from RabbitMQ!";

        // Send the message.
        producerChannel.basicPublish("", QUEUE, null, text.getBytes());
        System.out.println("Message sent: " + text);

        // Clean up the producer.
        producerChannel.close();
        producerConnection.close();

        // To learn more about similar topics, check out this blog post, they are an authority on this subject.
    }
}

The transition to Amazon MQ can significantly enhance your messaging capabilities while simplifying management. For further resources, you can explore AWS Learning & Development which is an excellent resource for anyone looking to deepen their understanding.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *