デッドレターキューとは何か
デッドレターキューとは、システム間でメッセージ(注文情報や通知データなど)をやり取りする仕組みの中で、正常に処理できなかったメッセージを削除せずに退避させておく、専用の保管場所のことです。英語では"Dead Letter Queue"、略して「DLQ」と呼ばれることもあります。
メッセージを使ったシステム連携(メッセージキュー)では、送信側がメッセージを送り、受信側がそれを受け取って処理する、という流れが基本です。しかし、受信側の処理でエラーが起きたり、メッセージの形式がおかしかったりして、どうしても処理できないメッセージが発生することがあります。そうしたメッセージを闇に葬らず、あとで調査できる形で残しておくのが、デッドレターキューの役割です。
「不達郵便」に例えると
郵便物で、宛先が間違っていたり、宛先の建物がすでに存在しなかったりして届けられない場合、その郵便物はゴミとして捨てられるわけではありません。郵便局の「不達郵便」を扱う窓口に集められ、差出人への返送や、原因の確認が行われます。
デッドレターキューも同じ発想です。「届けられなかったメッセージ」を、システムの正常な処理の流れから外に取り分けておくことで、後から「なぜ届かなかったのか」を確認できる状態を保ちます。もしこの仕組みがなければ、失敗したメッセージはそのまま消えてしまい、「何かのデータが処理されずに欠けている」ことにすら気づけなくなってしまいます。
メッセージがデッドレターキューに移されるまでの流れ
- 送信側がメッセージをキュー(待ち行列)に送信する
- 受信側がメッセージを取り出して処理を試みる
- 処理に失敗する(エラー、タイムアウト、形式不正など)
- 一定回数のリトライを行っても、なお失敗し続ける
- そのメッセージが、通常のキューからデッドレターキューへ移される
- 開発者・運用担当者が、デッドレターキューの中身を確認し、原因調査や再送を行う
ポイントは、1回失敗しただけで即座にデッドレターキューへ送るわけではなく、一定回数のリトライを経てもなお失敗する場合に移される、という点です。一時的なネットワークの乱れなどによる失敗であれば、リトライだけで解決することも多いためです。
デッドレターキューがないと、何が起きるか
- 失敗したメッセージがそのまま消えてしまい、データの欠落に誰も気づけない
- 原因調査ができないまま、同じ種類の失敗が繰り返される
- 「処理できないメッセージ」が延々とリトライされ続け、システム全体のリソースを圧迫する
特に厄介なのが1つ目です。エラーがログに一瞬出るだけで処理自体は次に進んでしまうような構成だと、後から「あの時のあの注文データが処理されていなかった」と気づくのが、ずっと後になってからということも珍しくありません。デッドレターキューは、そうした「静かに消えていく失敗」を可視化する役割も担っています。
運用でよくある悩みどころ
- 溜まったメッセージを放置してしまう:仕組みとして退避はできていても、定期的に中身を確認する運用が伴っていないと、結局失敗に気づけないまま溜まり続けることになります
- 再送すべきか、破棄すべきかの判断基準が曖昧:一時的な不具合が直ってから再送すれば解決するものもあれば、データ自体が根本的に誤っていて再送しても意味がないものもあります。この見極めのルールを決めておく必要があります
- 監視・アラートとの連携を忘れがち:デッドレターキューにメッセージが溜まったこと自体を検知する仕組みがないと、確認そのものが後回しになりがちです
似た仕組みとの違い
以前紹介したサーキットブレーカーパターンが「不調な相手への呼び出し自体を一時的に止める」仕組みであるのに対し、デッドレターキューは「呼び出し(処理)を試みた結果、失敗したものを取り分けておく」仕組みです。どちらも障害への向き合い方という点では共通していますが、片方は「そもそも呼ばない」、もう片方は「呼んだ結果失敗したものを残す」という、異なる場面で使われる考え方です。
こうして見ると
デッドレターキューは、派手な機能ではありませんが、「失敗を見えなくしない」という地味ながら重要な役割を果たす仕組みです。複数のシステムがメッセージをやり取りする構成を扱う際は、正常系だけでなく、この「失敗した時にどう残すか」まで設計に組み込んでおく価値があります。
※ 具体的な実装方法は、使用しているメッセージキューサービス(Amazon SQS、RabbitMQ、Azure Service Busなど)によって設定方法が異なるため、詳しくは各公式ドキュメントもあわせてご確認ください。