見出し画像

LocalでSQS(ElasticMQ)を動かしてみた

はじめに

こんにちは、SHIFT の開発部門に所属しているmurasawaです。今期より中途で入社し、バックエンド関連の開発を担当しています。

現在、研修でデータベースやRestAPIについて基本的な事から学んでいます。学んだことをアウトプットし理解を深めていくとともに技術の共有として役に立てば幸いです。

今回開発作業でLocalでQueueを作成しメール送信の際の動作確認を行いました。その際の手順や、気を付けるべきことをまとめました。

動作環境
OS:windows10
仮想環境VirtualBox CentOS7.5
使用docker image:softwaremill/elasticmq-native:1.2.0

aws cli2の設定

今回、awsコマンドを用いてqueueの作成や確認を行います。

下記公式サイトを参考にaws cli2をインストールしてください。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-linux.html

aws-cliの接続設定

今回はローカルでqueueを使い開発に役立てるのが目的なので実際にAWSに接続はしませんが、configureは設定しておく必要があります。

以下のようにダミーで設定してください。

[user@localhost docker_test]$aws configure
AWS Access Key ID [None]: *****************
AWS Secret Access Key [None]: *****************
Default region name [None]: ap-northeast-1
Default output format [None]: json

これでaws cliの設定は完了です。

docker-composeでelasticmqを起動する

ローカルでテストする時には、AWS SQS互換のElasticMQを用います。
docker-composeのセットアップは以下記事が大変参考になります。
https://qiita.com/youtangai/items/ff67ceff5497a0e0b1af

docker-composeの用意ができたら以下のようなdocker-compose.yamlを作成してください。

docker-compose.yamlversion: '1.0'
services:
  elasticmq:
    container_name: elasticmq
    image: softwaremill/elasticmq-native:1.2.0
    ports:
      - "9324:9324"
      - "9325:9325"

作成したら、docker-compose.yamlを配置したフォルダで

[user@localhost docker_test]$docker-compose up -d

と実行してください。
upは起動、-dは指定することでターミナルが占有されないようバックグラウンド実行にできます。

以下のように表示されれば起動完了です。

[user@localhost docker_test]$ docker-compose up -d
Creating network "docker_test_default" with the default driver
Pulling elasticmq (softwaremill/elasticmq-native:1.2.0)...
1.2.0: Pulling from softwaremill/elasticmq-native
ddad3d7c1e96: Pull complete
def39899535b: Pull complete
91b01f24d580: Pull complete
b32bcd4023f4: Pull complete
922408bc00a1: Pull complete
2963c4b32118: Pull complete
Digest: sha256:2a585a33fde4e89be2ea50fece640369908328134eeab7645c93029436d06a70
Status: Downloaded newer image for softwaremill/elasticmq-native:1.2.0
Creating elasticmq ... done
[user@localhost docker_test]$ 

ElasticMQにQueueを作成

Queueを作成してURLを取得してください。
ではaws create queueと検索して出てきたコマンドを実行してみるとします。

[user@localhost docker_test]$ aws sqs create-queue --queue-name ses-queue

An error occurred (AccessDenied) when calling the CreateQueue operation: \
Access to the resource https://sqs.ap-northeast-1.amazonaws.com/ is denied.
[user@localhost docker_test]$ 

アクセスできないと怒られてしまいました。
デフォルトでは普通にcreate queueしようとするとlocalhostのElasticMQではなく、 awsに接続しようとしてエラーになります。

なのでしっかり--endpoint-url http://localhost:9324のようにendpointを指定して、アクセスすべきurlを指定してあげてください。

[user@localhost docker_test]$ aws sqs create-queue --queue-name ses-queue --endpoint-url http://localhost:9324
{
    "QueueUrl": "http://localhost:9324/000000000000/ses-queue"
}
[user@localhost docker_test]$

これで"QueueUrl": "http://localhost:9324/000000000000/ses-queue"が作成されました。

下記コマンドで作成されているqueueのリストを見ることができます

[user@localhost docker_test]$ aws sqs list-queues --endpoint-url http://localhost:9324
{
    "QueueUrls": [
        "http://localhost:9324/000000000000/ses-queue"
    ]
}
[user@localhost docker_test]$ 

Queueにメッセージを送信、受信

Queueにメッセージを送信

以下コードを実行してメッセージが格納されるか確認します。

参考:https://k5-n.com/elasticmq/
JavaScriptでAWS-CLIコマンドを実行するために、本記事ではnode.jsのaws-sdkライブラリ を使用しています。

以下send.jsを作成し実行します。

send.jsconst aws = require('aws-sdk');

const endpointUrl = 'http://localhost:9324';
const queueUrl = endpointUrl + '/000000000000/ses-queue';

const sqs = new aws.SQS({
  apiVersion: '2021-02-05',
  endpoint: endpointUrl,
});

const params = {
  DelaySeconds: 10,
  MessageAttributes: {
    Title: {
      DataType: 'String',
      StringValue: 'test',
    },
    Author: {
      DataType: 'String',
      StringValue: 'murasawa',
    },
    WeeksOn: {
      DataType: 'Number',
      StringValue: '5',
    },
  },
  MessageBody: 'test',
  QueueUrl: queueUrl,
};

sqs.sendMessage(params, (e, data) => {
 if (e) {
   console.log('Error', e);
 } else {
   console.log('Success', data.MessageId);
 }
});

上記コードでは

const sqs = new aws.SQS({
  apiVersion: '2021-02-05',
  endpoint: endpointUrl,
});

の部分でアクセスするSQSを定義し、

sqs.sendMessage(params, (e, data) => {
 if (e) {
   console.log('Error', e);
 } else {
   console.log('Success', data.MessageId);
 }
});

部分でメッセージを送信しています。

実行します。

[user@localhost docker_test]$node send.js
Success 080f35fd-dcbf-4fe9-abd1-7f0ddb374663
[user@localhost docker_test]$

実行したら下記コマンドでqueueにメッセージが格納されているか確認します。

[user@localhost docker_test]$ aws sqs receive-message \
--queue-url http://localhost:9324/000000000000/ses-queue \
--endpoint-url http://localhost:9324
{
    "Messages": [
        {
            "MessageId": "080f35fd-dcbf-4fe9-abd1-7f0ddb374663",
            "ReceiptHandle": "080f35fd-dcbf-4fe9-abd1-7f0ddb374663#095239c4-d7fe-4a1a-aa67-1efbb70058d4",
            "MD5OfBody": "5a105e8b9d40e1329780d62ea2265d8a",
            "Body": "test1"
        }
    ]
}
//閲覧を終了したい場合はEscキーを押してください
[user@localhost docker_test]$

Queueのメッセージを受信して確認

以下receive.jsを実行してqueueに格納されているメッセージを受信して確認します。

receive.jsconst aws = require('aws-sdk');

const endpointUrl = 'http://localhost:9324';
const queueUrl = endpointUrl + '/000000000000/ses-queue';

const sqs = new aws.SQS({
  apiVersion: '2021-02-05',
  endpoint: endpointUrl,
});

async function poll() {
  const params = {
    QueueUrl: queueUrl,
    MaxNumberOfMessages: 10,
    WaitTimeSeconds: 20,
    MessageAttributeNames: ['Title', 'Author', 'WeeksOn'],
  };
  return new Promise((resolve, reject) => {
    sqs.receiveMessage(params, (e, data) => {
      if (e) {
        console.error(e);
        reject(e);
      } else {
        console.log(data);
        resolve(data);
      }
    });
  });
}
  
async function main() {
  const data = await poll();
}

main();

実行

[user@localhost docker_test]$node receive.js
{
  ResponseMetadata: { RequestId: '00000000-0000-0000-0000-000000000000' },
  Messages: [
    {
      MessageId: '080f35fd-dcbf-4fe9-abd1-7f0ddb374663',
      ReceiptHandle: '080f35fd-dcbf-4fe9-abd1-7f0ddb374663#86606b99-3251-48c8-8c27-66cccba407d5',
      MD5OfBody: '5a105e8b9d40e1329780d62ea2265d8a',
      Body: 'test1',
      MD5OfMessageAttributes: '21f736d18ae5577f37c735bc7650d34d',
      MessageAttributes: [Object]
    }
  ]
}
[user@localhost docker_test]$

メッセージの削除とqueueの削除

特定のメッセージを削除したい場合は

[user@localhost docker_test]$ aws sqs receive-message \
--queue-url http://localhost:9324/000000000000/ses-queue \
--endpoint-url http://localhost:9324
{
    "Messages": [
        {
            "MessageId": "080f35fd-dcbf-4fe9-abd1-7f0ddb374663",
            "ReceiptHandle": "080f35fd-dcbf-4fe9-abd1-7f0ddb374663#91337845-0d5e-49c4-921d-5be46d9f95b6",
            "MD5OfBody": "5a105e8b9d40e1329780d62ea2265d8a",
            "Body": "test1"
        }
    ]
}
//閲覧を終了したい場合はEscキーを押してください
[user@localhost docker_test]$

でReceiptHandleを確認して下記コマンドを実行。

[user@localhost docker_test]$ aws sqs delete-message \
--queue-url http://localhost:9324/000000000000/ses-queue \
--receipt-handle 080f35fd-dcbf-4fe9-abd1-7f0ddb374663#91337845-0d5e-49c4-921d-5be46d9f95b6 \
--endpoint-url http://localhost:9324
$ 

[user@localhost docker_test]$ aws sqs receive-message \
--queue-url http://localhost:9324/000000000000/ses-queue \
--endpoint-url http://localhost:9324
$ 

削除されます。

そしてqueueの削除

[user@localhost docker_test]$ aws sqs delete-queue \
--queue-url http://localhost:9324/000000000000/ses-queue \
--endpoint-url http://localhost:9324
$ 

削除されました。

[user@localhost docker_test]$ aws sqs list-queues --endpoint-url http://localhost:9324
$

終わりに

Local環境でのSQSの使い方やコマンドでのメッセージの確認方法などをまとめました。
開発で使いこなすことはできそうですが、実際のSQSを使った経験が少ないのでこれからどんどん触っていきたいと思います。
触っていく中でさらに記事を書き理解を深めていきたいと思います。

__________________________________

執筆者プロフィール:Satoshi Murasawa
前社ではRPAツールの技術サポート、開発を1年半経験。 SHIFTでは、バックエンドエンジニアとして入社し、node.jsやmysqlに触れはじめた。
DBに漠然とした興味があり、勉強して部の中でDB関連で役割を持つことができたらよいなと思っています。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/