Open4

SQS

mocknmockn

概要

https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html

特徴

  • Amazon Simple Queue Service (Amazon SQS) は、分散ソフトウェア システムとコンポーネントを統合および分離できる、安全で耐久性のあるメッセージキューサービス。
  • プロデューサーはSQSのキューにメッセージを送信し、コンシューマーはキューからメッセージを取得し処理を行う。
  • コンシューマーは、キューに対して定期的/不定期にポーリングを行いメッセージの存在を確認する必要がある。(プル型)
  • コンシューマーはメッセージの処理が完了した場合、キューからメッセージを削除する必要がある。
  • メッセージの読み取り回数が上限に達した時、Dead Letter Queue(DLQ)にメッセージを退避することで、後続処理実行やエラーの調査等を行うことができる。

ショートポーリング・ロングポーリング

https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html#sqs-long-polling
https://qiita.com/taka_22/items/718ec340a710bbf5e3d0

  • ポーリング時間の長さ。
  • 基本的にはロングポーリングが推奨。ロングポーリンのグタイムアウトは20秒(最大値)を設定する。

SQSはリクエスト課金なので、出来るだけリクエスト数を少なくした方が良い。つまり、ロングポーリングタイムアウト秒を最大に設定することで、リクエスト回数を減らし、コストを抑えることが出来る。

可視性タイムアウト

https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html
https://qiita.com/s_9_i/items/dfb14a57487844d365d5

  • メッセージの重複処理を避けるため、あるコンシューマーがメッセージを処理している間は別のコンシューマーが処理できないようメッセージを不可視にする期間。RDBのロックのようなもの。
  • デフォルトの可視性タイムアウトは30秒。最小0秒、最大12時間。
  • SQSキューのメッセージは処理後も残り続けるため、コンシューマーでの処理の最後に明示的に削除する必要がある。
  • 可視性タイムアウトはこの削除処理が完了するまでの期間を設定する必要があるので注意。

Dead Letter Queue (DLQ)

Cloud Formation

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html

アクセス権限

https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonSQSFullAccess.html
https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-basic-examples-of-iam-policies.html

  • AmazonSQSFullAccess

https://dev.classmethod.jp/articles/sns-sqs-subscribe-access-policy/
https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-overview-of-managing-access.html

  • AWSサービスからSQSにアクセス(メッセージの送受信等)するにはアクセスポリシーに追加する必要がある。
mocknmockn

Java (Spring Boot)

Spring Cloud AWS

https://zenn.dev/yyamada12/articles/dd08cda8b7ff01
https://spring.pleiades.io/spring-cloud-aws/docs/3.0.2/reference/html/index.html#sqslistener-annotation
Spring Cloud AWSのSQSライブラリを使用すると楽に実装できる。
古い情報が多いので注意。最新はSpringBoot3に対応している。

LocalStack

https://qiita.com/Brutus/items/89eb03be7c7bd9d6911d
ローカルでの動確のため、LocalStackを利用してSQSをローカルにエミュレートする。
ローカルのAWSサービスはDockerコンテナ上で起動する。

mocknmockn

ECS

起動方法パターン

  1. SQSのメッセージ数をトリガーとして、オートスケーリングポリシーを使用しECSタスクを起動する
  2. ECS Shceduled TaskでSQSをポーリングし、メッセージを受信した場合にECSタスクを起動する
  3. SQSトリガーでLambdaを起動し、LambdaからECSタスクを起動する
  4. SQSトリガーでStep Functionsを起動し、LambdaからECSタスクを起動する

1. SQSのメッセージ数をトリガーとして、オートスケーリングポリシーを使用しECSタスクを起動する

https://dev.classmethod.jp/articles/sqs-to/

  • メリット
    • SQS→Lambda→ECSタスクという構成に比べてこの構成の良さはコードがLambdaに分散せずコンテナに集約されることにある。
  • デメリット
    • 代償としてスケーリングポリシーの考慮と学習が必要になる。

2. ECS Shceduled TaskでSQSをポーリングし、メッセージを受信した場合にECSタスクを起動する

https://tech.connehito.com/entry/2017/09/13/171914

  • メリット
    • Dockerベースにすることで、各環境差異でバッチがこけるリスクを回避しつつ、ジョブスケジューラを構築せずとも、AWS ECS Task Schedulerの見やすいビューワーでバッチを一覧して管理出来る。
    • エラーに関しても、cloud watch logsで拾えるので、ほとんど開発や構築なしにAWSマネージドサービスで構築できる。
  • デメリット
    • ジョブスケジューラにあるようなジョブチェーンの実行やリトライは出来ない。
    • リトライに関しては、エラー通知トリガでRunTaskを実行するか、手動実行する必要がある。

3. SQSトリガーでLambdaを起動し、LambdaからECSタスクを起動する

4. SQSトリガーでStep Functionsを起動し、LambdaからECSタスクを起動する