跳到主要内容

AMQP 消息头

QWen Plus 中英对照 AMQP Message Headers

概述

Spring Integration AMQP 适配器会自动映射所有 AMQP 属性和头信息。(这与 4.3 版本有所不同——之前,只有标准头信息会被映射)。默认情况下,这些属性是通过使用 DefaultAmqpHeaderMapper 复制到 Spring Integration MessageHeaders 和从 MessageHeaders 复制的。

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

AMQP MessageProperties 中的任何用户定义的头信息都会复制到 AMQP 消息中或从 AMQP 消息中复制出来,除非被 DefaultAmqpHeaderMapperrequestHeaderNamesreplyHeaderNames 属性明确否定。默认情况下,对于出站映射器,不映射任何 x-* 头信息。有关原因,请参阅本节后面出现的注意事项

要覆盖默认行为并恢复到 4.3 之前的 behavior,请在属性中使用 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 (see The contentType Header)

  • 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_* 模式。

important

如果你有一个以 ! 开头的自定义标题,并且你希望映射它,则需要用 \ 转义它,如下所示:STANDARD_REQUEST_HEADERS,\!myBangHeader。名为 !myBangHeader 的标题现在已被映射。

备注

从 5.1 版开始,DefaultAmqpHeaderMapper 将回退到将 MessageHeaders.IDMessageHeaders.TIMESTAMP 映射到 MessageProperties.messageIdMessageProperties.timestamp,如果传出消息中不存在对应的 amqp_messageIdamqp_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 不再映射到头部地图中的条目。