What is it, naokirin?

Amazon SQSと互換性のあるElasticMQでローカルで完結できるようにする

AWSでアプリケーションを開発していると、複数システム間を疎結合にする目的でAmazon SQSを利用することがあります。

一方でこうしたSaaS系に分類されるサービスは、ローカルの開発環境で動作を完結できず、ローカルでの開発中も、開発用に個別にAWSのサービスを開発メンバーごとに用意するなどが必要になってしまいます。

こうしたときにAmazon SQSについては、ElasticMQを利用することで、ローカルでSQS互換なサーバーを立ち上げて実行することができます。

ElasticMQとは

ElasticMQは、Scalaで開発されているAmazon SQS互換なメッセージキューシステムのOSSです。Apache License 2.0で公開されているため、商用利用も可能なようです。
一方で In-memory queue なため、永続化はできません。ローカルの開発用途だけを考えれば、この点はそこまで問題はないでしょう。

github.com

ElasticMQをローカルで立ち上げる

すでにDockerHubに公式のイメージがあるので、こちらをdocker compose で起動します。

# docker-compose.yml
version: '3'

services:
  elasticmq:
    image: softwaremill/elasticmq
    ports:
    - "9324:9324"
    - "9325:9325"
    volumes:
    - type: bind
      source: ./custom.conf
      target: /opt/elasticmq.conf

custom.conf に設定済みのキューを記載しておくことで、起動時点でキューの設定がされた状態になります。公式の例ですが、可視性タイムアウト、デッドレターキュー、FIFOの設定などもちゃんとできるようになっています。

queues {
  queue1 {
    defaultVisibilityTimeout = 10 seconds
    delay = 5 seconds
    receiveMessageWait = 0 seconds
    deadLettersQueue {
      name = "queue1-dead-letters"
      maxReceiveCount = 3 // from 1 to 1000
    }
    fifo = false
    contentBasedDeduplication = false
    copyTo = "audit-queue-name"
    moveTo = "redirect-queue-name"
    tags {
      tag1 = "tagged1"
      tag2 = "tagged2"
    }
  }
  queue1-dead-letters { }
  audit-queue-name { }
  redirect-queue-name { }
}

個々まで準備できれば、 docker compose up で起動できます。

実際にアクセスしてみる

aws cli でアクセスしてみましょう。

まずはキューを作成してみます。

$ aws sqs create-queue --queue-name queue --endpoint-url http://localhost:9324

{
    "QueueUrl": "http://localhost:9324/000000000000/queue"
}

次にメッセージを送信してみます。

$ aws sqs send-message --queue-url http://localhost:9324/000000000000/queue --message-body "hello, sqs" --endpoint-url http://localhost:9324

{
    "MD5OfMessageBody": "d8e961672b33bcd8f136253c656681f9",
    "MessageId": "1ec7c3f3-07ec-4481-835b-9d494ee8d634"
}

最後にメッセージを受信してみます。

$ aws sqs receive-message --queue-url http://localhost:9324/000000000000/queue --endpoint-url http://localhost:9324
{
    "Messages": [
        {
            "MessageId": "1ec7c3f3-07ec-4481-835b-9d494ee8d634",
            "ReceiptHandle": "1ec7c3f3-07ec-4481-835b-9d494ee8d634#6e09c3d0-c463-40b9-bb8d-f669ea7ddf63",
            "MD5OfBody": "d8e961672b33bcd8f136253c656681f9",
            "Body": "hello, sqs"
        }
    ]
}

このように、ローカルでAmazon SQSと同等の操作が可能になります。

まとめ

クラウドSaaS系サービスの欠点の一つであるローカル開発時の手間を、Amazon SQSに関してはElasticMQをを活用することで軽減することができます。