SQSのDLQ、システム全体で1つにまとめるのは微妙

  • AWS
  • SQS
  • DLQ

この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。

結論

SQSのDLQ(Dead Letter Queue)をシステム全体で1個にまとめて運用するのは、基本的にはやめた方がいい。サービスや機能ごとに専用のDLQを作る方が、後々の運用がだいぶ楽になる。

なぜ1個にまとめない方がいいか

理由は単純で、原因の違うエラーが同じキューに混ざるから。

  • Lambda側のエラーとSNSの配信失敗が同じDLQに入ると、どっちが原因かログを見るまでわからない
  • サービスごとに最適な再試行回数(maxReceiveCount)や保持期間は違うのに、1つのDLQにまとめると設定を揃えるしかなくなる
  • メッセージ量が多いサービスと少ないサービスが同居すると、少ない方のエラーが埋もれる

トラブルシュートの起点になるべきDLQが、逆に調査対象を広げてしまうのは本末転倒。

flowchart LR
    A[メイン処理: サービスA] -->|失敗| DLQ_A[DLQ for A]
    B[メイン処理: サービスB] -->|失敗| DLQ_B[DLQ for B]
    C[メイン処理: サービスC] -->|失敗| DLQ_C[DLQ for C]

サービスごとに分けておけば、アラームが鳴った時点でどのキューのDLQかで原因の見当がつく。1個にまとめると、そこから中身を開いて仕分けする作業が毎回発生する。

モニタリングと再処理

DLQの監視はCloudWatchのApproximateNumberOfMessagesVisibleメトリクスでアラームを組むのが基本。メッセージが1件でも入ったら通知が飛ぶようにしておくと、放置されるのを防げる。

再処理については、SQSにはDLQからメッセージを送信元キューや別の宛先キューへ戻す「redrive」という機能がある。コンソールからの操作に加えて、StartMessageMoveTask / ListMessageMoveTasks / CancelMessageMoveTask というAPIでプログラム的に自動化することもできる。手動でDLQの中身を確認して個別に再送、という運用しかできないわけではない。

制約として覚えておくこと

DLQは送信元キューと同一のAWSアカウント・同一リージョンにある必要がある。別リージョンのDLQに向けるといった構成は組めないので、設計時点で意識しておく必要がある。