Dead Letter Channel Pattern with RabbitMQ

RabbitMQ 2.8 以降では expire したメッセージや拒否されたメッセージを dead letter として専用の exchange に転送する事ができる。

dead letter になるユースケース
以下のケースで、メッセージは dead letter になる

  • The message is rejected (basic.reject or basic.nack) with requeue=false
  • The TTL for the message expires

Enterprise Integratin Patterns との対比

Gregor Hohpe & Bobby Woolf の “Enterprise Integratin Patterns” では


Invalid Message Channel

The receiver should move the improper message to an Invalid Message Channel, a special channel for messages that could not be processed by their receivers.

Dead Letter Channel

What will the messaging system do with a message it cannot deliver?

When a messaging system determines that it cannot or should not deliver a message, it may elect to move the message to a Dead Letter Channel.

Message Lifecycle

Dead Letter Exchange の使い方

キューの宣言で arguments x-dead-letter-exchange を指定する。

  'x-message-ttl' : 1000,
  "x-dead-letter-exchange" : "dlx",
  "x-dead-letter-routing-key" : "dl", # if not specified, queue's routing-key is used

x-dead-letter-routing-key を指定しなかった場合、 メッセージに設定された x-dead-letter-routing-key が利用される。

Dead-Lettered Message の特徴

  • confirm mode
  • exchange 名が dead letter exchange のものに書き換えられる
  • ルーティングキーが書き換えられる(x-dead-letter-routing-key を指定した場合)
  • 'x-death' ヘッダーが追加される。

ヘッダーで特に有益なのは dead letter の原因を表す reason フィールド。以下のいずれかの値を取る。

  • expired – the TTL of the message expired
  • rejected – the message was rejected with requeue=false

注意点としては、 dead letter message を受け取るまでは invalid message で reject されたのか expire したのか判断がつかない。

x-death ヘッダーの詳細は Dead Letter Exchanges のドキュメントを参照のこと。


“Work Queues” チュートリアルをベースにして、 キューに TTL を追加し、ワーカーで basic.reject を実装し、意図的に dead letter を発生させて動作を確認。


メッセージに TTL(time to live)を設定するには、キューの宣言で arguments x-message-ttl をミリ秒で指定する。

  'x-message-ttl' : 1000,


キューのコールバック関数で basic_reject すれば OK.


[gist /]




$ python a
 [x] Sent 'a'
$ python b
 [x] Sent 'b'
$ python c
 [x] Sent 'c'
$ python d
 [x] Sent 'd'
$ python e
 [x] Sent 'e'

1/2 の確率で sleep または reject する

$ python
 [*] Waiting for messages. To exit press CTRL+C
 [x] Received 'a'
 [x] Done
 [x] Received 'b'
 [x] Rejected
 [x] Received 'e'
 [x] Done

dead-letter worker

reject されたメッセージ または TTL が過ぎたメッセージを処理する。

$ python
 [*] Waiting for dead-letters. To exit press CTRL+C
 [x] <BasicProperties(["headers={'x-death': [{'queue': 'task_queue', 'reason': 'expired', 'exchange': '', 'routing-keys': ['task_queue'], 'time': datetime.datetime(2012, 10, 6, 11, 53, 22)}]}"])>
 [reason] : expired : 'c'
 [x] <BasicProperties(["headers={'x-death': [{'queue': 'task_queue', 'reason': 'expired', 'exchange': '', 'routing-keys': ['task_queue'], 'time': datetime.datetime(2012, 10, 6, 11, 53, 24)}]}"])>
 [reason] : expired : 'd'
 [x] <BasicProperties(["headers={'x-death': [{'queue': 'task_queue', 'reason': 'rejected', 'exchange': '', 'routing-keys': ['task_queue'], 'time': datetime.datetime(2012, 10, 6, 11, 53, 24)}]}"])>
 [reason] : rejected : 'b'


Tagged with: , , , ,
Posted in middleware

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: