AMQP 消息头

概述

Spring Integration AMQP适配器会自动映射所有AMQP属性和头部。(这与4.3版本有所不同——之前,只映射标准头部)。默认情况下,这些属性使用DefaultAmqpHeaderMapper复制到Spring Integration MessageHeaders中,以及从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不再映射到头部映射中的条目。