死信Exchange
云消息隊列 RabbitMQ 版的死信Exchange適用于處理被消費者否定應答或重試失敗的消息。本文介紹死信Exchange的核心概念、路由流程、配置方式、注意事項和更多信息。
核心概念
死信Exchange
用于路由死信消息的Exchange。死信Exchange會根據Binding Key、死信Routing Key、Header屬性將死信消息投遞至死信Queue。死信Exchange可以是任何一種常見類型的Exchange,例如Direct Exchange。
死信Routing Key
死信消息的路由規則。如果不設置死信消息的Routing Key,則死信消息的Routing Key默認為消息本身的Routing Key。
死信消息
死信Queue
死信Exchange綁定的Queue,用于存儲死信消息。
路由流程
死信Exchange路由死信消息的流程如下:
生產者將消息發送到Exchange。
Exchange將消息路由到Queue。
消費者從Queue拉取消息。
消費者消費失敗后消息重試次數超過16次依然沒有成功,或者消費者沒有消費消息而直接否定應答,消息變成死信消息。
Queue根據x-dead-letter-exchange將死信消息發送到死信Exchange,并根據x-dead-letter-routing-key為死信消息設置死信Routing Key。
死信Exchange將死信消息路由到死信Queue。
注意事項
云消息隊列 RabbitMQ 版不支持跨Vhost路由死信消息,即Queue被指定的死信Exchange必須和該Queue在同一個Vhost內。
云消息隊列 RabbitMQ 版不支持修改Queue的死信Exchange。如果您需要修改某個Queue的死信Exchange,您需要刪除該Queue后,在重新創建時設置死信Exchange。
配置方式
云消息隊列 RabbitMQ 版支持以下方式配置死信Exchange:
控制臺
您可以在云消息隊列 RabbitMQ 版控制臺創建Queue時,為其配置死信Exchange。
在概覽頁面的資源分布區域,選擇地域。
在實例列表頁面,單擊目標實例名稱。
在左側導航欄,單擊Queue 列表。
在Queue 列表頁面,在當前 Vhost右側的切換下拉列表中,選擇Vhost,單擊創建 Queue。
在創建 Queue面板,在Queue 名稱文本框輸入Queue的名稱,選擇是否為Auto Delete類型,單擊高級選項,設置Queue的參數,然后單擊確定。
參數
描述
說明
Queue 名稱
Queue的名稱
只能包含字母、數字、短劃線(-)、下劃線(_)、半角句號(.)、井號(#)、正斜線(/)、at符號(@)。
長度限制在1~255字符。
創建后無法修改,只能刪除重建。
以amq.開頭的為保留字段,因此不能使用。例如:amq.test。
Auto Delete
最后一個Consumer取消訂閱后,Queue是否自動刪除。
true:在訂閱該Queue消息的最后一個Consumer取消訂閱該Queue的消息后,自動刪除該Queue。
false:在訂閱該Queue消息的最后一個Consumer取消訂閱該Queue的消息后,不自動刪除該Queue。
高級選項
Queue的參數設置,可用于設置死信Exchange、死信Routing Key和消息存活時間。
DeadLetterExchange:指定死信消息發送的目標Exchange。
DeadLetterRoutingKey:指定死信消息的Routing Key,即死信Exchange會將消息發送至匹配該死信Routing Key所對應的Queue。
MessageTTL:消息存活時間,單位毫秒(ms)。在指定時間內未被成功消費的消息會變成死信消息,該消息將會被發送到死信Exchange。更多信息,請參見消息存活時間。
API
您可以在通過API創建Queue時,為其配置死信Exchange。更多信息,請參見CreateQueue。
客戶端
您可以在云消息隊列 RabbitMQ 版客戶端聲明Queue時,為其配置死信Exchange。
通過x-dead-letter-exchange和x-dead-letter-routing-key設置死信消息要發送的Exchange以及死信消息的Routing Key。
例如,聲明一個名稱為some.exchange.name
、類型為direct
的Exchange,使用 x-dead-letter-exchange將該Exchange設置為死信Exchange,使用x-dead-letter-routing-key將死信消息的Routing Key設置為demo-routing-key
。
Java示例代碼如下:
channel.exchangeDeclare("some.exchange.name", "direct");
Map<String, Object> args = new HashMap<String, Object>();
arguments.put("x-dead-letter-exchange", "some.exchange.name");
arguments.put("x-dead-letter-routing-key", "demo-routing-key");
channel.queueDeclare("MyQueue", false, false, false, arguments);
死信Header
死信消息Header中包含以下信息:
Header | 說明 |
x-first-death-exchange | 消息第一次成為死信時的交換機。 |
x-first-death-queue | 消息第一次成為死信時的隊列。 |
x-first-death-reason | 消息第一次成為死信時的原因。 |
x-death-total | 消息成為死信的次數。 |
x-death | 包含更多關于死信的詳細信息的數組。
|
消息成為死信消息的可能原因如下:
expired(消息過期)
nack(消息nack且requeue為false)
reject(消息被拒絕且requeue為false)
exceed consumer times(消費次數超限)
開啟死信隊列的TTL功能
默認情況下,死信消息進入死信隊列后,TTL(Time-To-Live,存活時間)功能會被禁用,這意味著死信消息進入死信隊列后,不會因存活時間到期而路由到其它死信隊列或被自動刪除。您可以通過控制臺啟用實例的死信隊列TTL功能。啟用后,死信消息被轉移到死信隊列后,將遵循死信隊列設置的TTL能力,在存活時間過期后被轉發到其它死信隊列。
實例限制
支持開啟TTL功能的實例類型有:Serverless系列實例、預付費系列實例中的企業版和鉑金版。
操作步驟
在云消息隊列 RabbitMQ 版實例列表頁面,單擊目標實例名稱。
在實例詳情頁面,單擊實例使用限制頁簽。
在是否支持死信隊列的TTL功能右側單擊開通,為死信隊列開啟TTL功能。
在配置死信隊列時,存在形成消息循環的風險。例如,將隊列A的死信隊列設置為隊列B,并將隊列B的死信隊列設置為隊列A,那么會形成一個死信消息的循環路由。如果在整個路由循環中沒有出現任何消息拒絕(reject)事件,一旦檢測到這種循環,涉及的死信消息將不再具有TTL功能。
死信消息在多個隊列間的路由次數限制為最多16次,一旦達到路由次數上限,相關死信消息將不再具有TTL功能。
更多信息
關于如何刪除死信Exchange和為死信Exchange綁定死信Queue,請參見Exchange管理。