AMQP 訊息頭
概述
Spring Integration AMQP 介面卡會自動對映所有 AMQP 屬性和頭。(這是 4.3 版本後的一項變更——之前僅對映標準頭)。預設情況下,這些屬性使用 DefaultAmqpHeaderMapper 在 Spring Integration MessageHeaders 之間進行復制。
您可以傳入自己實現的 AMQP 特定頭對映器,因為介面卡具有支援這樣做的屬性。
AMQP MessageProperties 中任何使用者定義的頭都將被複制到或從 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 專有屬性/頭也會被複制。例如,當您使用聯合時,收到的訊息可能具有名為 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 對映中的一個條目;這是不正確的,而且,由於底層的 Spring AMQP 訊息轉換器可能更改了內容型別,因此該值可能不正確。這種更改將反映在頂級 content_type 屬性中,但不會反映在 RabbitMQ 頭對映中。入站對映會忽略頭對映值。 contentType 不再對映到頭對映中的一個條目。