AMQP 消息头

概述

Spring Integration AMQP 适配器会自动映射所有 AMQP 属性和头。(这是 4.3 版本后的一项变更——之前仅映射标准头)。默认情况下,这些属性使用 DefaultAmqpHeaderMapper 在 Spring Integration MessageHeaders 之间进行复制。

您可以传入自己实现的 AMQP 特定头映射器,因为适配器具有支持这样做的属性。

AMQP MessageProperties 中任何用户定义的头都将被复制到或从 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 不再映射到头映射中的一个条目。

© . This site is unofficial and not affiliated with VMware.