この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、コンサルティング部 もこ@札幌オフィス です!
当エントリは弊社コンサルティング部による『AWS再入門ブログリレー 2019』の22日目のエントリです。
このブログリレーの企画は、普段AWSサービスについて最新のネタ・深い/細かいテーマを主に書き連ねてきたメンバーの手によって、 今一度初心に返って、基本的な部分を見つめ直してみよう、解説してみようというコンセプトが含まれています。
AWSをこれから学ぼう!という方にとっては文字通りの入門記事として、またすでにAWSを活用されている方にとってもAWSサービスの再発見や2019年のサービスアップデートのキャッチアップの場となればと考えておりますので、ぜひ最後までお付合い頂ければ幸いです。
本日22日目のテーマは『Amazon Simple Queue Service』です。
目次
- 目次
- Amazon Simple Queue Service(SQS)とは?
- 前提知識
- SQSのタイプ
- 標準キュー
- FIFOキュー
- FIFOキューの制限
- SQSのライフサイクル
- SQSを使ってアプリケーションを作ってみた
- (レジ) ハンバーガーの注文を受け付ける
- (厨房) ハンバーガーの注文を処理する
- まとめ
Amazon Simple Queue Service(SQS)とは?
Amazon Simple Queue Service(以下SQS)はフルマネージド型のメッセージキューサービスです。
「メッセージをSQSの送信」、「SQSからメッセージをポーリング」することができ、SQSを利用することによって
- 軽い受付処理をした結果をSQSに登録し、別のサーバーからメッセージをポーリングし、重い処理を済ませる
-
SQS側で処理予定のタスクをバッファーでき、スパイク的なアクセスに耐えれる構成を作成できる
-
SQSに登録されているキューに基づいてSQSをポーリングし、処理を行うサーバーをスケールする事ができる
-
SQSをトリガーにLambdaをキックし、サーバーレスが捗る
などなどで、お店で例えて言うと
「注文はチーズバーガー→お会計130円です→チーズバーガーを作成→チーズバーガーを返す」
ような同期的なアプリケーションを
「レジ側: 注文はチーズバーガー→お会計130円です(SQSにキューを登録)」
「厨房側: SQSをポーリング、チーズバーガーを作成、チーズバーガーを返す」
のように、レジと厨房を非同期で処理できるため、レジでは注文と会計のみの仕事に集中もできますし、何よりチーズバーガーを作る作業は厨房に丸投げするため、お客様にも待たさずに次々と注文を受け付けられます。
また、キューの量をトリガーにスケールすることも可能です。
前提知識
メッセージをSQSに送信するアプリケーションのことを「プロデューサー」と呼び、
SQSからメッセージをポーリングするアプリケーションのことを「コンシューマー」と呼びます。
SQSに送信できる最大サイズは256KBで、SQS側での最長保持期間は14日です。
SQSのタイプ
SQSには2つの種類があり、「標準キュー」、「FIFOキュー」があります。
標準キュー
「順不同な可能性がある」、「複数回配信される可能背がある」、「ほぼ無制限に送信ができる」、標準的なキューです。
(1, 2, 3, 4)->SQS->(2, 4, 1, 3, 4)
のように順不同で配信される可能性があり、同じメッセージを複数回配信される可能性があります。
複数回同じメッセージを受け取っても悪影響が出ないよう、DynamoDBなどを利用して重複が無いようにする必要があります。
FIFOキュー
「順番配信」、「重複キューの削除」、「一回だけの配信」、「1秒に送信できるキューに制限がある」キューです。
つまり、
(1, 2, 3, 4)->SQS->(1, 2, 3, 4)
となり、DynamoDBなどを利用して重複処理を回避する必要もなくなります!
FIFOキューの制限
SendMessage、ReceiveMessage、DeleteMessageは 300 Message/s
SendMessageBatch、DeleteMessageBatch、ChangeMessageVisibilityBatchを利用すると最大 3000 Message/sとなります。
(SendMessageBatchなどのBatch系では最大10件のメッセージを一つのリクエストで送信することができます)
また、FIFOキューではLambda, SNSなどの連携をサポートしていないため、利用する場合は標準キューを利用する必要があります。
SQSのライフサイクル
SQSには主に「可視性タイムアウト」、「メッセージ保持期間」の設定があります。
可視性タイムアウトは、「コンシューマーがメッセージを受信してから可視性タイムアウトの間、他のコンシューマーなどにキューを配信しない」ものです。
メッセージ保持期間は「SQSにメッセージ保持する期間」で、SQSに登録されてから処理されずにSQSに溜まったメッセージが削除されるまでの期間です。
SQSを使ってアプリケーションを作ってみた
ここまでSQSについて紹介しましたが、実際に使ってみないとよくわからないと思います。
実際にSQSを利用し、「ハンバーガーの注文を受け、厨房で作成する」ものを作ってみたいと思います。
(レジ) ハンバーガーの注文を受け付ける
//@ts-check
const AWS = require("aws-sdk");
const SQS = new AWS.SQS({ region: "ap-northeast-1" })
const QueueUrl = "https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/queue";
function order(burger, amount) {
const MessageBody = JSON.stringify({ burger, amount })
SQS.sendMessage({
MessageBody,
QueueUrl,
}, (err, data) => {
if (err) return console.error(err, err.stack);
console.log(data)
});
}
order("チーズバーガー", 10);
(厨房) ハンバーガーの注文を処理する
//@ts-check
const AWS = require("aws-sdk");
const sqs = new AWS.SQS({ region: "ap-northeast-1" });
const QueueUrl = "https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/queue";
const receiveMessage = QueueUrl =>
new Promise((resolve, reject) => {
const params = {
QueueUrl,
MaxNumberOfMessages: 10,
WaitTimeSeconds: 10
};
sqs.receiveMessage(params, (err, data) => {
if (err || !data.Messages) return reject(err);
return resolve(data);
});
});
const deleteMessage = (ReceiptHandle, QueueUrl) => {
const params = {
QueueUrl,
ReceiptHandle
};
sqs.deleteMessage(params, (err, data) => {
if (err) return console.error(err);
console.log("delete queue");
console.log(data);
});
};
const createBurger = burger =>
new Promise(resolve => {
setTimeout(() => resolve("?"), 3000);
});
async function main() {
while (true) {
const data = await receiveMessage(QueueUrl).catch(console.error);
if (!data) continue;
for (const message of data.Messages) {
// ハンバーガーを作る
const order = JSON.parse(message.Body);
// 重い処理
console.log(order.burger)
const result = await createBurger(order.burger);
console.log(result)
messageids.push(message.MessageId);
deleteMessage(message.ReceiptHandle, QueueUrl);
}
}
}
main();
標準SQSを利用しているため、実際に利用する場合はDynamoDBを使うなどで受信側で重複を回避する必要があるので、注意が必要です。
まとめ
このように、SQSを利用すると簡単にサービスを分離することができ、AWS側にキューの処理などをまるまる任せられるので、とても便利です!
今回の「AWS再入門ブログリレー」もおかげさまで非常に皆様の高評価を戴いた企画となりました。ご支持戴き誠にありがとうございました!
本リレーを通してAWSのたくさんある様々なサービスに再入門できたなら幸いです!