AMQP 訊息標頭

總覽

Spring Integration AMQP 配接器會自動對應所有 AMQP 屬性和標頭。(這是 4.3 版的變更 - 之前,僅對應標準標頭)。預設情況下,這些屬性會使用 DefaultAmqpHeaderMapper 複製到 Spring Integration MessageHeaders 和從 Spring Integration MessageHeaders 複製。

您可以傳入您自己的 AMQP 特定標頭對應器實作,因為配接器具有支援這樣做的屬性。

AMQP MessageProperties 內的任何使用者定義標頭都會複製到 AMQP 訊息或從 AMQP 訊息複製,除非 DefaultAmqpHeaderMapperrequestHeaderNamesreplyHeaderNames 屬性明確否定。預設情況下,對於輸出對應器,不會對應任何 x-* 標頭。請參閱本節稍後出現的 注意事項,以了解原因。

若要覆寫預設值並還原為 4.3 之前的行為,請在屬性中使用 STANDARD_REQUEST_HEADERSSTANDARD_REPLY_HEADERS

在對應使用者定義的標頭時,值也可以包含要比對的簡單萬用字元模式(例如 thing**thing)。* 符合所有標頭。

從 4.1 版開始,AbstractHeaderMapperDefaultAmqpHeaderMapper 超類別)允許為 requestHeaderNamesreplyHeaderNames 屬性設定 NON_STANDARD_HEADERS 權杖(除了現有的 STANDARD_REQUEST_HEADERSSTANDARD_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(也不會對應 thing2thing3)。標準標頭加上 badqux 會對應。否定技術可能很有用,例如,當接收器下游以不同方式完成 JSON 還原序列化邏輯時,不對應輸入訊息的 JSON 類型標頭。為此,應為輸入通道配接器/閘道器的標頭對應器設定 !json_* 模式。

如果您有一個以 ! 開頭的使用者定義標頭,而您確實想要對應它,則需要使用 \ 來逸出它,如下所示:STANDARD_REQUEST_HEADERS,\!myBangHeader。現在會對應名為 !myBangHeader 的標頭。
從 5.1 版開始,如果輸出訊息上不存在對應的 amqp_messageIdamqp_timestamp 標頭,DefaultAmqpHeaderMapper 將會回退,分別將 MessageHeaders.IDMessageHeaders.TIMESTAMP 對應到 MessageProperties.messageIdMessageProperties.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 不再對應到標頭對應中的項目。