RabbitMQ学習(十三):デッドレタースイッチ(Dead Letter Exchanges)


説明
前編のブログ「RabbitMQ学習(十二):キューとメッセージの有効期間」では、公式ドキュメントのキューとメッセージに関するTTLを翻訳学習しました.メッセージのTTLは再試行キューを遅らせる重要な要素ですが、メッセージの有効期間だけでは期限切れのメッセージの消費を実現できません.このブログでは、公式ドキュメントのデッドラインスイッチ(DLX)に関する内容を翻訳学習し続け、このスイッチにより、期限切れのメッセージの再ルーティングを実現し、遅延再試行を実現します.
本文
概要
キュー内のメッセージは、デッドメッセージ(dead-lettered)になり、次のイベントのいずれかが発生すると、メッセージはスイッチに再送信されます.
  • メッセージは消費者によってbasicを使用する.プロジェクトまたはbasic.nackメソッドでrequeueパラメータ値をfalseに設定メッセージ確認(negatively acknowledged)
  • を行う.
  • メッセージは、メッセージ有効期間(per-message TTL)により
  • が期限切れとなる.
  • メッセージは、キューがその長さの制限を超えるために破棄される
  • .
    キューの有効期間によってメッセージが期限切れになることはありません.
    デッドラインスイッチ(DLXs)は、通常のスイッチであり、任意のタイプであってもよいし、通常の一般的な方法で宣言してもよい.
    いずれのキューに対しても、デッドラインスイッチは、クライアントでキューパラメータを使用して宣言するか、サーバでpolicyコマンドを使用して宣言を作成できます.この2つの方法を同時に使用してデッドラインスイッチを宣言すると、キューパラメータ宣言の方法が優先されます.
    アプリケーションの再配置によって再構成されないため、policyコマンドを使用してデッド・メッセージ・スイッチを構成する方法が推奨されます.
    policy構成の使用(Configuration Using a Policy)
    policyコマンドを使用して、デッドラインスイッチを構成します.コマンドで「dead-letter-exchange」パラメータの値を指定できます.たとえば、次のようにします.
    rabbitmqctl set_policy DLX ".*" '{"dead-letter-exchange":"my-dlx"}' --apply-to queues
    
    以上のコマンドは、my-dlxという名前のデッドシグナルスイッチを構成し、すべてのキューに適用することを宣言します.これは単なる例であり、実際に使用すると、異なるキューが異なるデッドラインスイッチを設定するか、設定しないかのいずれかです.
    同様に、policyコマンドで「dead-letter-routing-key」パラメータ値を指定することで、ルーティングキーを指定することもできます.
    オプションのキュー・パラメータ構成の使用(Configuration Using Optional Queue Arguments)
    キューにデッドシグナルスイッチを設定する場合は、キューを宣言するときにオプションのパラメータ「x-dead-letter-exchange」を使用して構成を宣言できます.このパラメータ値は、キューと同じ仮想ホストのスイッチ名でなければなりません.
    channel.exchangeDeclare("some.exchange.name", "direct");
    
    Map args = new HashMap<>();
    args.put("x-dead-letter-exchange", "some.exchange.name");
    channel.queueDeclare("myqueue", false, false, false, args);
    
    以上のコードはsomeという新しい名前を宣言した.exchange.nameのスイッチで、この新しいスイッチを新しいキューのデッドシグナルスイッチとして設定します.キューを宣言するときにデッドラインスイッチが宣言されている必要はありませんが、メッセージにデッドラインルーティングが必要な場合は、スイッチが存在しなければなりません.そうしないと、メッセージは破棄されます.
    デッドラインルーティングで使用するルーティングキーを指定することもできます.設定されていない場合は、メッセージ自体の元のルーティングキーを使用します.
    args.put("x-dead-letter-routing-key", "some-routing-key");
    
    デッドラインスイッチが指定されている場合、通常の構成宣言キューの権限に加えて、ユーザーはキューの読み取り権限とデッドラインスイッチの書き込み権限を必要とします.キューのペアが宣言されると、これらの権限が検証されます.
    ルートデッドメッセージ
    デッド・メッセージは、キューのデッド・スイッチによって他のキューにルーティングされます.ルーティングには2つのケースがあります.
  • キューを宣言するときに指定されたデッドラインルーティングキー
  • を使用する.
  • が設定されていない場合、メッセージ自体の元のルーティングキー
  • が使用する.
    たとえば、fooをルーティングキーとしてスイッチにメッセージを送信すると、メッセージがデッドメッセージになった後、fooをルーティングキーとしてキューのデッドメッセージスイッチに送信します.キューが宣言時に「x-dead-letter-routing-key」の値をbarと指定すると、メッセージがデッドシグナルスイッチに送信されるとbarがルーティングキーとして使用されます.
    キューにデッド・メッセージ・ルーティング・キーが設定されていない場合、メッセージはデッド・メッセージ・ルーティング・キーによって使用されます.これにはCCとBCCヘッダパラメータ設定のルーティングキーが含まれる.
    デッド・メッセージが再送信されると、メッセージ確認メカニズムも内部でオンになります.したがって、元のキューがこのメッセージを削除する前に、メッセージが最終的に到着したキューであるデッド・メッセージ・キューは、メッセージを確認する必要があります.すなわち、送信キューは、デッドラインキューの確認メッセージを受信するまで元のメッセージを削除しない.特にサーバがダウンタイムしている場合、同じメッセージは元のキューとデッドラインキューで同時に表示されます.
    メッセージのデッドシグナルルーティングは、ループを形成する可能性があります.たとえば、1つのキューのデッドメッセージのメッセージが、指定されたデッドメッセージルーティングキーを使用してデフォルトのスイッチに送信されていない場合.メッセージは、ループ全体(メッセージが同じキューに2回到着する)で拒否されず、メッセージは破棄されます.
    メッセージへのデッド・メッセージの影響(Dead-Lottered Effects on Messages)
    デッドラインメッセージはヘッダ情報を変更しました.
  • スイッチの名前が最後のデッドレタースイッチ
  • に変更されました.
  • ルーティングキーは、キューによって指定されたデッドラインルーティングキー
  • に変更することができる.
  • 以上が発生すると、CCというヘッダパラメータは
  • 削除される.
  • BCCという名前のヘッダパラメータは
  • 削除される.
    デッドラインルーティングを行うと、各デッドラインメッセージのヘッダにx-deathという配列が追加されます.この配列には、デッドロックルーティングのたびに情報エンティティが含まれ、キー値対{queue,reason}で区別されます.各エンティティは、次のフィールド情報を含むテーブルです.
  • queue:メッセージがデッドメッセージと呼ばれるときに存在するキューの名前
  • reason:メッセージがデッドメッセージになった原因
  • time:メッセージがデッドメッセージになった時間は、64ビットのタイムスタンプ
  • です.
  • exchange:メッセージが送信スイッチ(メッセージが複数回デッドメッセージと呼ばれる場合、この値はデッドメッセージスイッチ)
  • .
  • routing-keys:メッセージ送信時に使用するルーティングキーで、CCキーを含むがBCC
  • を含まない
  • count:この理由でメッセージがデッドラインルーティングされた回数
  • .
  • original-expiration(メッセージのTTLによってメッセージのTTLがデッドメッセージと呼ばれる場合、この値がある):メッセージの元の有効期限属性.この値は、メッセージがデッドメッセージルーティングされたときに削除され、メッセージが他のキューで再び有効期限が切れることを避けるために
  • である.
    新しい情報エンティティは、x-death配列の先頭に送信され、配列に同じキューと同じデッドラインの原因の情報エンティティがすでに存在する場合、エンティティのcountフィールドに1が加算され、エンティティは配列の先頭に移動します.
    reasonという属性の値は、メッセージがデッドメッセージになった理由を表し、以下のいくつかがあります.
  • rejected:メッセージはメッセージ担当者によって拒否され、requeueパラメータ値はfalse
  • である.
  • expired:メッセージのTTLが期限切れになったため
  • maxlen:キューが許可する最大長
  • を超える
    メッセージが最初にルーティングされると、3つのトップレベルのヘッダ情報が追加されます.
  • x-first-death-reason
  • x-first-death-queue
  • x-first-death-exchange
  • メッセージが最初のデッドラインルーティングを行う場合、設定されたreason、queue、exchangeフィールドの値と同じです.追加すると、値は変更されません.
    この配列は、最近発生した時間に従って並べ替えられるので、最近のデッドシグナルルーティングは、最初のエンティティに記録されます.
    ドキュメントのアドレス:https://www.rabbitmq.com/dlx.html