AMQP 訊息頭
概述
Spring Integration AMQP 介面卡會自動對映所有 AMQP 屬性和訊息頭。(這是從 4.3 版本開始的變更 - 以前僅對映標準訊息頭)。預設情況下,這些屬性使用 DefaultAmqpHeaderMapper
在 Spring Integration MessageHeaders
之間來回複製。
您可以傳入自己的 AMQP 特定訊息頭對映器實現,因為介面卡支援透過屬性進行此操作。
AMQP MessageProperties
中的任何使用者定義訊息頭都會複製到 AMQP 訊息或從 AMQP 訊息複製,除非被 DefaultAmqpHeaderMapper
的 requestHeaderNames
或 replyHeaderNames
屬性明確否定。預設情況下,對於出站對映器,不會對映任何 x-*
訊息頭。有關原因,請參閱本節後面出現的注意事項。
要覆蓋預設設定並恢復到 4.3 版本之前的行為,請在屬性中使用 STANDARD_REQUEST_HEADERS
和 STANDARD_REPLY_HEADERS
。
對映使用者定義訊息頭時,值也可以包含簡單的萬用字元模式(例如 thing* 或 *thing )進行匹配。* 匹配所有訊息頭。 |
從 4.1 版本開始,AbstractHeaderMapper
(DefaultAmqpHeaderMapper
的超類)允許為 requestHeaderNames
和 replyHeaderNames
屬性配置 NON_STANDARD_HEADERS
令牌(除了現有的 STANDARD_REQUEST_HEADERS
和 STANDARD_REPLY_HEADERS
),以對映所有使用者定義的頭。
org.springframework.amqp.support.AmqpHeaders
類標識了 DefaultAmqpHeaderMapper
使用的預設訊息頭
-
amqp_appId
-
amqp_clusterId
-
amqp_contentEncoding
-
amqp_contentLength
-
content-type
(參見contentType
訊息頭) -
amqp_correlationId
-
amqp_delay
-
amqp_deliveryMode
-
amqp_deliveryTag
-
amqp_expiration
-
amqp_messageCount
-
amqp_messageId
-
amqp_receivedDelay
-
amqp_receivedDeliveryMode
-
amqp_receivedExchange
-
amqp_receivedRoutingKey
-
amqp_redelivered
-
amqp_replyTo
-
amqp_timestamp
-
amqp_type
-
amqp_userId
-
amqp_publishConfirm
-
amqp_publishConfirmNackCause
-
amqp_returnReplyCode
-
amqp_returnReplyText
-
amqp_returnExchange
-
amqp_returnRoutingKey
-
amqp_channel
-
amqp_consumerTag
-
amqp_consumerQueue
如本節前面所述,使用 * 訊息頭對映模式是複製所有訊息頭的常用方法。然而,這可能會產生一些意外的副作用,因為某些 RabbitMQ 專有屬性/訊息頭也會被複制。例如,當您使用聯合交換器 (federation) 時,接收到的訊息可能有一個名為 x-received-from 的屬性,其中包含傳送訊息的節點。如果您在入站閘道器上使用萬用字元 * 進行請求和回覆訊息頭對映,此訊息頭會被複制,這可能會導致聯合出現問題。此回覆訊息可能會被聯合回傳送代理,傳送代理可能會認為訊息正在迴圈,並因此靜默丟棄它。如果您希望使用萬用字元訊息頭對映的便利性,您可能需要在下游流中過濾掉一些訊息頭。例如,為了避免將 x-received-from 訊息頭複製回回復,您可以在將回復發送到 AMQP 入站閘道器之前使用 <int:header-filter … header-names="x-received-from"> 。或者,您可以明確列出您實際希望對映的屬性,而不是使用萬用字元。出於這些原因,對於入站訊息,對映器(預設情況下)不對映任何 x-* 訊息頭。它也不將 deliveryMode 對映到 amqp_deliveryMode 訊息頭,以避免該訊息頭從入站訊息傳播到出站訊息。相反,此訊息頭被對映到 amqp_receivedDeliveryMode ,該訊息頭在輸出時不會被對映。 |
從 4.3 版本開始,訊息頭對映中的模式可以透過在模式前加上 !
來否定。被否定的模式具有優先順序,因此像 STANDARD_REQUEST_HEADERS,thing1,ba*,!thing2,!thing3,qux,!thing1
這樣的列表不會對映 thing1
(也不會對映 thing2
和 thing3
)。標準訊息頭以及 bad
和 qux
會被對映。否定技術對於例如在接收器下游以不同方式執行 JSON 反序列化邏輯時不對映 JSON 型別訊息頭非常有用。為此,應為入站通道介面卡/閘道器的訊息頭對映器配置 !json_*
模式。
如果您有一個以 ! 開頭的使用者定義訊息頭,並且您確實希望對映它,則需要使用 \ 進行轉義,如下所示:STANDARD_REQUEST_HEADERS,\!myBangHeader 。名為 !myBangHeader 的訊息頭現在被映射了。 |
從 5.1 版本開始,如果出站訊息上不存在相應的 amqp_messageId 或 amqp_timestamp 訊息頭,DefaultAmqpHeaderMapper 將回退到分別將 MessageHeaders.ID 和 MessageHeaders.TIMESTAMP 對映到 MessageProperties.messageId 和 MessageProperties.timestamp 。入站屬性將像以前一樣對映到 amqp_* 訊息頭。在訊息消費者使用有狀態重試時,填充 messageId 屬性非常有用。 |
contentType
訊息頭
與其他訊息頭不同,AmqpHeaders.CONTENT_TYPE
沒有字首 amqp_
;這使得 contentType 訊息頭可以在不同的技術之間透明傳遞。例如,傳送到 RabbitMQ 佇列的入站 HTTP 訊息。
contentType
訊息頭被對映到 Spring AMQP 的 MessageProperties.contentType
屬性,然後該屬性被對映到 RabbitMQ 的 content_type
屬性。
在 5.1 版本之前,此訊息頭也被對映為 MessageProperties.headers
map 中的一個條目;這是不正確的,而且,由於底層的 Spring AMQP 訊息轉換器可能改變了內容型別,該值可能是錯誤的。這種變化會反映在一等(first-class)的 content_type
屬性中,但不會反映在 RabbitMQ headers map 中。入站對映會忽略 headers map 中的值。contentType
不再對映到 headers map 中的一個條目。