跳到主要内容
版本:7.0.2

消息历史

DeepSeek V3 中英对照 Message History

消息架构的关键优势在于松耦合,使得参与组件之间无需相互感知。仅凭这一点,应用程序就具备了极高的灵活性,允许您更改组件而不影响流程的其他部分、调整消息路由、切换消息消费方式(轮询与事件驱动)等。然而,当出现问题时,这种简洁的架构风格可能会带来调试困难。在调试过程中,您通常希望获取尽可能多的消息相关信息(如消息来源、经过的通道及其他详细信息)。

消息历史记录是一种模式,它通过提供维护消息路径一定程度的可见性选项来帮助您,无论是用于调试目的还是维护审计追踪。Spring Integration 提供了一种简单的方式来配置您的消息流,以维护消息历史记录,方法是在消息中添加一个头部,并在每次消息通过被跟踪的组件时更新该头部。

消息历史配置

要启用消息历史记录,您只需在配置中定义 message-history 元素(或使用 @EnableMessageHistory),如下例所示:

@Configuration
@EnableIntegration
@EnableMessageHistory

现在,每个已命名的组件(即定义了 'id' 的组件)都会被追踪。框架会在你的消息中设置 'history' 头部,其值为 List<Properties>

考虑以下配置示例:

@MessagingGateway(defaultRequestChannel = "bridgeInChannel")
public interface SampleGateway {
...
}

@Bean
@Transformer(inputChannel = "enricherChannel", outputChannel="filterChannel")
HeaderEnricher sampleEnricher() {
HeaderEnricher enricher =
new HeaderEnricher(Collections.singletonMap("baz", new StaticHeaderValueMessageProcessor("baz")));
return enricher;
}

上述配置生成了一个简单的消息历史结构,输出效果类似于:

[{name=sampleGateway, type=gateway, timestamp=1283281668091},
{name=sampleEnricher, type=header-enricher, timestamp=1283281668094}]

要获取消息历史记录,您只需访问 MessageHistory 头部。以下示例展示了如何操作:

Iterator<Properties> historyIterator =
message.getHeaders().get(MessageHistory.HEADER_NAME, MessageHistory.class).iterator();
assertTrue(historyIterator.hasNext());
Properties gatewayHistory = historyIterator.next();
assertEquals("sampleGateway", gatewayHistory.get("name"));
assertTrue(historyIterator.hasNext());
Properties chainHistory = historyIterator.next();
assertEquals("sampleChain", chainHistory.get("name"));

你可能不希望追踪所有组件。为了将历史记录限制在基于组件名称的特定组件上,你可以提供 tracked-components 属性,并指定一个以逗号分隔的组件名称和模式列表,以匹配你想要追踪的组件。以下示例展示了如何实现:

@Configuration
@EnableIntegration
@EnableMessageHistory("*Gateway", "sample*", "aName")

在前面的示例中,仅对以 'Gateway' 结尾、以 'sample' 开头或完全匹配名称 'aName' 的组件维护消息历史记录。

此外,MessageHistoryConfigurer bean 现在通过 IntegrationMBeanExporter 作为 JMX MBean 公开(参见 MBean 导出器),允许您在运行时更改模式。但请注意,必须停止该 bean(关闭消息历史记录)才能更改模式。此功能可能对临时开启历史记录以分析系统非常有用。该 MBean 的对象名称为 <domain>:name=messageHistoryConfigurer,type=MessageHistoryConfigurer

important

在应用程序上下文中,只能声明一个 @EnableMessageHistory(或 <message-history/>)作为组件追踪配置的单一来源。不要为 MessageHistoryConfigurer 使用通用的 bean 定义。

备注

在 6.3 版本之前,消息历史记录头是不可变的(您无法重写历史):每次追踪不仅会创建新的 MessageHistory 实例,还会创建全新的消息副本。现在它以仅追加模式工作:第一次追踪会创建一个带有新 MessageHistory 容器的新消息。其余所有 MessageHistory.write() 调用都会向现有头添加新条目,而不会创建新消息。这显著提升了应用程序性能。框架中所有可能将同一消息发送给多个消费者(PublishSubscribeChannelAbstractMessageRouterWireTap 等)的组件,或基于输入消息生成多个输出的拆分器,现在都会将现有的 MessageHistory 头克隆到这些新消息中。对于框架范围外的任何其他多生产者用例,建议使用 AbstractIntegrationMessageBuilder.cloneMessageHistoryIfAny() API,以确保并行的下游子流程能够贡献自己的消息历史追踪。