こうこく
作 ▸
改 ▸

Node.jsでAmazon SQSをロングポーリングするサンプル

AWSのSQSで左から右に流すやり方を調べてて、以下の記事を見かけました。ロングポーリングというのが便利そうだったので、調べてNode.jsで書いてみました。

Amazon SQSを効率よく処理するための簡単なサンプルコード(perl / python) - アルパカDiary Pro

Node.js v9.6.1

前提

ローカルのプログラムからAWSのリソースにアクセスするために、アクセスキーが必要です。持ってなければ、IAMユーザーを用意してアクセスキーを作成しておきます。

アクセスキーを作成したら、それを実行環境に認証情報として設定する必要があります。

ホームディレクトリ (Windowsなら C:\Users\ユーザー名) に .aws というフォルダが無ければ作成します。その中に credentials というファイルを作成し、内容を以下の通りにします。

~.aws/credentials
[default]
aws_access_key_id = アクセスキーを記入
aws_secret_access_key = シークレットアクセスキーを記入

以下のリンクはAWS SDK for Javaのドキュメントですが、上記の内容は『AWS 認証情報の設定』の項と同じなので、参照してください。

開発用の AWS 認証情報とリージョンのセットアップ - AWS SDK for Java

なお、AWS-CLIをインストールして aws configure しても、同じことができます。

AWS CLI の設定 - AWS Command Line Interface

サンプル

まず、サンプルを実行するためにカラのフォルダを作って、npm で aws-sdk をインストールしておきます。

npm install --save-dev aws-sdk

このフォルダの中にサンプルのソースコードを example.js として設置し、node コマンドで実行します。

以下のサンプルは、東京リージョンでFIFOキューを使って作りました。

起動すると最長20秒間隔でロングポーリングし、メッセージがあれば10個ずつ取り出して表示したあと、キューから削除します。それを永遠に繰り返します。

example.js
const AWS = require('aws-sdk');
AWS.config.update({
    region: 'ap-northeast-1',  // リージョンを入力
});
const sqs = new AWS.SQS();
const QUEUE_URL = 'https://sqs.ap-northeast-1.amazonaws.com/999999999999/my-queue.fifo';  // メッセージキューURLを入力

(async () => {
    try {
		// 永遠に繰り返す
        while(true) {
            console.log('★待機中...');

            // 20秒のロングポーリングで10個ずつメッセージ受信
            const data = await sqs.receiveMessage({
                QueueUrl: QUEUE_URL,
                MaxNumberOfMessages: 10,
                WaitTimeSeconds: 20
            }).promise();

            // カラならまた待機
            if (!data.Messages) {
                console.log('★メッセージなし');
                continue;
            }

            // メッセージあれば順次処理
            for (let i = 0, len = data.Messages.length; i < len; ++i) {
                const message = data.Messages[i];

                // メッセージ表示
                console.log('★メッセージ' + i);
                console.log(message);

                // メッセージ削除
                await sqs.deleteMessage({
                    QueueUrl: QUEUE_URL,
                    ReceiptHandle: message.ReceiptHandle,
                }).promise();

                console.log('★メッセージ'+ i +'を削除しました');
            }
        }
    } catch (e) {
        console.log('エラー!', e);
    }
})();

「待機中」と表示されている間に当該キューに適当なメッセージを送ると、以下のような感じになります。

実行結果
★待機中...
★メッセージなし
★待機中...
★メッセージ0
{ MessageId: '3be5393d-3aae-4788-8115-10e8412d5c08',
  ReceiptHandle: 'AQEBkyqIZ/tj+fOCPapMSFFLaBDzUXb5nynbRRlBC2rQeMHUEAVualScJCgN3xgbPmOILG7Zou0PUgSsbrpomPbFshjOnTe4x+v2VMTtjucB/IksirFYIRmyIAYE+3QV1/D0zyjGw+0NrK58x01O4GZHJC2Su9quljNMAIk5AwV19BTuT8sfQ6/eWdbwMiDTxsaEZIRmOyYTu9YfSlLpx9Tz/MOoqBhSG/7GAijLvXnPFSI3K/gAjUZgcBHns0YIWvnMZDpnUJWzo6VpJWycaLCTpPnbaPIbh5jCFE6RNbF8Awc=',
  MD5OfBody: '39fe81cfb0634fe34c5dcb71179ef339',
  Body: 'へろへろメッセージ!',
  Attributes:
   { SenderId: 'AIDAJS2I4CTJS7Z7RMO2K',
     ApproximateFirstReceiveTimestamp: '1547116074854',
     ApproximateReceiveCount: '1',
     SentTimestamp: '1547116074854',
     SequenceNumber: '18842805788872175616',
     MessageDeduplicationId: 'soukasouka',
     MessageGroupId: 'haihai' } }
★メッセージ0を削除しました
★待機中...

FIFOキューなので属性に MessageDeduplicationId がありますね。

飽きたら Ctrl+C で落としてください。

メモ

公式のAWS SDK for JavaScriptリファレンス。

Class: AWS.SQS ― AWS SDK for JavaScript

公式のロングポーリングのサンプル。

Enabling Long Polling in Amazon SQS - AWS SDK for JavaScript

この記事に何かあればこちらまで (非公開)