LoginSignup
30
18

More than 5 years have passed since last update.

メッセージキューの移行を考えてみる

Last updated at Posted at 2017-12-14

この記事は リクルートライフスタイル Advent Calendar 2017 の14日目の記事です。

はじめに

ホットペッパービューティーでシステム改善を行っている@akechiです。
システム改善の1つとして、RabbitMQの導入を推進しています。

メッセージキューといえば、AWS re:Invent 2017で「Amazon MQ」が発表されました。
Amazon MQの最大の利点は、移行の容易さです。
クラスメソッドさんの記事の通り、エンドポイントを切り替えるだけで移行ができちゃいます。
ただし、これはActiveMQから移行する場合の話です。

では、RabbitMQから移行する場合はどうなるのかを見ていきたいと思います。

RabbitMQでの送受信

まずはじめに、RabbitMQでの送受信の実装を見てみましょう。
一般的な実装方法として、RabbitMQのチュートリアルを参考にします。

RabbitMQSample.java

import com.rabbitmq.client.*;

import java.io.IOException;

public class RabbitMQSample {

    private final static String QUEUE_NAME = "testQueue";

    public static void main(String[] argv) throws Exception {
        // 前処理
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(ホスト名);
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        // メッセージの送信
        String message = "Hello World from RabbitMQ!";
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));

        // メッセージの受信
        Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
                    throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("Received '" + message + "'");
            }
        };
        channel.basicConsume(QUEUE_NAME, true, consumer);

        // 後処理
        channel.close();
        connection.close();
    }
}

Amazon MQでの送受信

次に、Amazon MQでの送受信の実装を見てみます。
実装方法はAmazon MQのチュートリアルを参考にします。
送受信の部分に関しては、ほとんど作り変えが必要になりますね。

AmazonMQSample.java
package amazon;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

public class AmazonMQSample {

    private final static String QUEUE_NAME = "testQueue";

    public static void main(String[] args) throws JMSException {

        // 前処理
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(エンドポイント);
        connectionFactory.setUserName(ユーザ名);
        connectionFactory.setPassword(パスワード);
        Connection connection = connectionFactory.createConnection();
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Destination destination = session.createQueue(QUEUE_NAME);

        // メッセージの送信
        MessageProducer producer = session.createProducer(destination);
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
        String text = "Hello World from Amazon MQ!";
        TextMessage producerMessage = session.createTextMessage(text);
        producer.send(producerMessage);

        // メッセージの受信
        MessageConsumer consumer = session.createConsumer(destination);
        Message consumerMessage = consumer.receive(1000);
        TextMessage consumerTextMessage = (TextMessage) consumerMessage;
        System.out.println("Message received: " + consumerTextMessage.getText());

        // 後処理
        producer.close();
        consumer.close();
        session.close();
        connection.close();
    }
}

SQSでの送受信

最後に、SQSでの送受信の実装も見てみましょう。
実装方法はこちらの例を参考にします。
Amazon MQと同様、送受信の部分は作り変えが必要になります。

SQSSample.java
package aws.example.sqs;

import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.AmazonSQSException;
import com.amazonaws.services.sqs.model.CreateQueueResult;
import com.amazonaws.services.sqs.model.Message;
import com.amazonaws.services.sqs.model.SendMessageBatchRequest;
import com.amazonaws.services.sqs.model.SendMessageBatchRequestEntry;
import com.amazonaws.services.sqs.model.SendMessageRequest;
import java.util.Date;
import java.util.List;

public class SQSSample {

    private final static String QUEUE_NAME = "testQueue";

    public static void main(String[] args) {
        // 前処理
        final AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();
        String queueUrl = sqs.getQueueUrl(QUEUE_NAME).getQueueUrl();

        // メッセージの送信
        SendMessageRequest send_msg_request = new SendMessageRequest()
                .withQueueUrl(queueUrl)
                .withMessageBody("Hello World from SQS!")
                .withDelaySeconds(5);
        sqs.sendMessage(send_msg_request);

        // メッセージの受信
        List<Message> messages = sqs.receiveMessage(queueUrl).getMessages();
        for (Message m : messages) {
            System.out.println("Message received: " + m.getBody());
            sqs.deleteMessage(queueUrl, m.getReceiptHandle());
        }
    }
}

移行の比較

RabbitMQからの移行コスト(実装)は、Amazon MQとSQSでほとんど同じだと思います。
ただ、移行して得られることはそれぞれ異なります。

移行 得られること
RabbitMQ -> Amazon MQ 運用工数の削減、可用性と耐久性
RabbitMQ -> SQS (上記に加えて)スケーラビリティ

おわりに

現時点では、RabbitMQから移行を考えた場合SQSの方が良いのかなと思います。
ただ、Amazon MQがActiveMQしかサポートしていない今の話で、今後RabbitMQをサポートするとまた話が変わってきますし、十分に考えられる未来だと思っています。

いづれにせよ変わらないことは、最終的にはSQSを使ったシステムに移行していくことがベストだということです。
Amazon MQとSQSの違いは以下のように記載されています。(引用元:https://docs.aws.amazon.com/ja_jp/amazon-mq/latest/developer-guide/welcome.html

Amazon MQ は Amazon SQS や Amazon SNS とはどう違うのですか?

Amazon MQ はマネージド型メッセージブローカーサービスであり、多くの一般的なメッセージブローカーと互換性があります。API (JMS など) や、プロトコル (AMQP、MQTT、OpenWire、Stomp など) との互換性に依存する既存のメッセージブローカーからのアプリケーション移行に Amazon MQ をお勧めします。

Amazon SQS および Amazon SNS はキューおよびトピックサービスであり、高度にスケーラブルでシンプルに使用でき、メッセージブローカーを管理する必要がありません。新規のアプリケーションには Amazon SQS および Amazon SNS をお勧めします。ほぼ無制限の拡張性とシンプルな管理がメリットです。

SQSという強力なメッセージキューサービスを展開しながら、顧客がSQSへの移行に困っていることに課題を感じ、新たにAmazon MQというサービスを提供する姿勢はやはりすごいなと思いました。

30
18
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
18