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` 不再映射到头部映射中的条目。