この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、CX事業本部 IoT事業部の若槻です。
Amazon SQSは、AWS上で疎結合でスケーラブルなシステムを実装するのに役立つフルマネージド型のメッセージキューイングサービスです。
しかし私は今までAmazon SQSを使う機会がなかなか無く、いい加減触ってみようかなと思っていたところ、ちょうど良さそうなチュートリアルを見つけたので、今回やってみました。
やってみた
やってみたのは、次のAmazon SQSメッセージを処理するLambda関数を作成するチュートリアルです。
実行ロールを作成する
Lambda関数実行用のIAMロールを作成します。
https://console.aws.amazon.com/iam/home#/roles を開き、[ロールの作成]をクリック。
[信頼されたエンティティ]でAWS サービス
、[ユースケースの選択]でLambda
を選択し、[次のステップ]をクリック。
AWSLambdaSQSQueueExecutionRole
を選択し、[次のステップ]をクリック。
ちなみにAWSLambdaSQSQueueExecutionRole
のポリシーの概要は次のようになります。Lambda関数がSQSメッセージを読み取り、CloudWatch Logsにログを書き込むためのアクセス許可です。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
[タグの追加]では何もせずに[次のステップ]をクリック。
[確認]では、[ロール名]でlambda-sqs-role
を指定して、[ロールの作成]をクリック。
作成できました。
関数を作成する
Node.jsランタイムで実行可能なLambda関数のハンドラーコードindex.js
を次の通り作成します。
index.js
exports.handler = async function(event, context) {
event.Records.forEach(record => {
const { body } = record;
console.log(body);
});
return {};
}
デプロイパッケージを作成します。
$ zip function.zip index.js
AWS CLIのlambda create-function
コマンドを実行してLambda関数を作成します。
$ ACCOUNT_ID=<アカウントID>
$ aws lambda create-function \
--function-name ProcessSQSRecord \
--zip-file fileb://function.zip \
--handler index.handler \
--runtime nodejs12.x \
--role arn:aws:iam::${ACCOUNT_ID}:role/lambda-sqs-role
マネジメントコンソールを見るとLambda関数がちゃんと作成されています。
関数をテストする
次のSQSメッセージのレコードを記載したinput.txt
ファイルを作成します。
input.txt
{
"Records": [
{
"messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
"receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
"body": "test",
"attributes": {
"ApproximateReceiveCount": "1",
"SentTimestamp": "1545082649183",
"SenderId": "AIDAIENQZJOLO23YVJ4VO",
"ApproximateFirstReceiveTimestamp": "1545082649185"
},
"messageAttributes": {},
"md5OfBody": "098f6bcd4621d373cade4e832627b4f6",
"eventSource": "aws:sqs",
"eventSourceARN": "arn:aws:sqs:ap-northeast-1:123456789012:my-queue",
"awsRegion": "ap-northeast-1"
}
]
}
lambda invoke
コマンドを次の通り実行します。するとInvalid base64
というエラーとなりました。
$ aws lambda invoke \
--function-name ProcessSQSRecord \
--payload file://input.txt outputfile.txt
Invalid base64: "{
"Records": [
{
"messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
"receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
"body": "test",
"attributes": {
"ApproximateReceiveCount": "1",
"SentTimestamp": "1545082649183",
"SenderId": "AIDAIENQZJOLO23YVJ4VO",
"ApproximateFirstReceiveTimestamp": "1545082649185"
},
"messageAttributes": {},
"md5OfBody": "098f6bcd4621d373cade4e832627b4f6",
"eventSource": "aws:sqs",
"eventSourceARN": "arn:aws:sqs:ap-northeast-1:123456789012:my-queue",
"awsRegion": "ap-northeast-1"
}
]
}
"
なるほどAWS CLI v2を使っている場合はペイロードをBase64エンコードする必要があるんですね。
簡単にまとめれば、バイナリパラメーター(blob)を指定する際にはBase64でエンコードしてね、ということです。lambda invokeの--payloadはblobで指定することになっています。そのためAWS CLI v2ではペイロードをBase64でエンコードする必要があるわけです。それでは実例も交えて確認してみましょう。
作業環境のAWS CLIバージョンを確認するとV2です。なのでBase64エンコードが必要です。
$ aws --version
aws-cli/2.0.28 Python/3.7.4 Darwin/20.6.0 botocore/2.0.0dev32
今回はとりあえずの回避策としてマネジメントコンソールからテストをしてみます。
実行できました。関数がSQSのメッセージのレコードを処理できています。
Amazon SQS キュー を作成する
Amazon SQS コンソールを開き、[キューを作成]をクリック。
ここでキューの設定が色々出来るのですが、標準キューで[名前]をMyQueue
と指定し、
[キューを作成]をクリック。
キューを作成できました。このキューのARNを控えます。
イベントソースを設定する
先程のARNを指定して、create-event-source-mapping
コマンドを次の通り実行します。これによりAmazon SQS キューと Lambda 関数の間イベントソースマッピングを設定します。
$ QUEUE_ARN=<キューのARN>
$ aws lambda create-event-source-mapping \
--function-name ProcessSQSRecord \
--batch-size 10 \
--event-source-arn ${QUEUE_ARN}
動作確認
先程作成したキューの詳細ページで[メッセージを送受信]をクリック。
[メッセージ本文]を指定して、[メッセージを送信]をクリックしキューメッセージを送信します。
Lambda関数のCloudWatch Logsのログイベントを見ると、キューメッセージを受信していることを確認できました!
おわりに
Amazon SQSメッセージを処理するLambda関数を作成するチュートリアルをやってみました。
Amazon SQSに関して今までは認定試験の勉強で仕様や実装パターンを覚えるだけの机上の知識しかありませんでしたが、今回触ってみて何となくの雰囲気がつかめました。
以上