Claim Check

在前面的章节中,我们介绍了几种内容丰富器组件,可以帮助您处理消息缺失数据的情况。我们还讨论了内容过滤,它允许您从消息中移除数据项。然而,有时我们希望临时隐藏数据。例如,在分布式系统中,我们可能会收到一个带有非常大 payload 的消息。一些间歇性的消息处理步骤可能不需要访问这个 payload,而有些可能只需要访问某些消息头,因此在每个处理步骤中携带大型消息 payload 可能会导致性能下降、产生安全风险,并使调试更加困难。

The Store in library(或称为 Claim Check)模式描述了一种机制,允许您将数据存储在已知位置,同时仅保留指向该数据位置的指针(即 Claim Check)。您可以将该指针作为新消息的 payload 传递,从而使消息流中的任何组件在需要时立即获取实际数据。这种方法与挂号信流程非常相似,您在邮箱中收到一个取件凭证,然后必须去邮局领取实际包裹。它也类似于航班或酒店行李提取的概念。

Spring Integration 提供了两种类型的 Claim Check 转换器

  • 入站 Claim Check 转换器

  • 出站 Claim Check 转换器

可以使用方便的基于命名空间的机制来配置它们。

入站 Claim Check 转换器

入站 Claim Check 转换器通过将其存储在由其 message-store 属性标识的消息存储中来转换入站消息。以下示例定义了一个入站 Claim Check 转换器

<int:claim-check-in id="checkin"
        input-channel="checkinChannel"
        message-store="testMessageStore"
        output-channel="output"/>

在上述配置中,在 input-channel 上接收到的消息被持久化到由 message-store 属性标识的消息存储中,并使用生成的 ID 进行索引。该 ID 就是该消息的 Claim Check。该 Claim Check 也成为发送到 output-channel 的新(转换后的)消息的 payload。

现在,假设在某个时刻您确实需要访问实际消息。您可以手动访问消息存储并获取消息内容,或者您可以使用相同的方法(创建转换器),只是现在您通过使用出站 Claim Check 转换器将 Claim Check 转换回实际消息。

以下列表概述了入站 Claim Check 转换器的所有可用参数

<int:claim-check-in auto-startup="true"             (1)
                    id=""                           (2)
                    input-channel=""                (3)
                    message-store="messageStore"    (4)
                    order=""                        (5)
                    output-channel=""               (6)
                    send-timeout="">                (7)
    <int:poller></int:poller>                       (8)
</int:claim-check-in>
1 生命周期属性,指示此组件是否应在应用程序上下文启动期间启动。默认为 true。此属性在 Chain 元素内部不可用。可选。
2 标识底层 bean 定义 (MessageTransformingHandler) 的 ID。此属性在 Chain 元素内部不可用。可选。
3 此端点的接收消息通道。此属性在 Chain 元素内部不可用。可选。
4 此 Claim Check 转换器使用的 MessageStore 引用。如果未指定,默认引用名为 messageStore 的 bean。可选。
5 指定此端点作为通道的订阅者连接时的调用顺序。当该通道使用 failover 调度策略时,这尤其重要。当此端点本身是带有队列的通道的轮询消费者时,此属性无效。此属性在 Chain 元素内部不可用。可选。
6 标识此端点处理消息后发送消息的消息通道。此属性在 Chain 元素内部不可用。可选。
7 指定将回复消息发送到输出通道时等待的最长时间(毫秒)。默认为 30 秒。此属性在 Chain 元素内部不可用。可选。
8 定义一个轮询器。此元素在 Chain 元素内部不可用。可选。

出站 Claim Check 转换器

出站 Claim Check 转换器允许您将带有 Claim Check payload 的消息转换为以原始内容作为其 payload 的消息。

<int:claim-check-out id="checkout"
        input-channel="checkoutChannel"
        message-store="testMessageStore"
        output-channel="output"/>

在上述配置中,在 input-channel 上收到的消息应以 Claim Check 作为其 payload。出站 Claim Check 转换器通过查询消息存储以获取由提供的 Claim Check 标识的消息,将其转换为带有原始 payload 的消息。然后,它将新取出的消息发送到 output-channel

以下列表概述了出站 Claim Check 转换器的所有可用参数

<int:claim-check-out auto-startup="true"             (1)
                     id=""                           (2)
                     input-channel=""                (3)
                     message-store="messageStore"    (4)
                     order=""                        (5)
                     output-channel=""               (6)
                     remove-message="false"          (7)
                     send-timeout="">                (8)
    <int:poller></int:poller>                        (9)
</int:claim-check-out>
1 生命周期属性,指示此组件是否应在应用程序上下文启动期间启动。默认为 true。此属性在 Chain 元素内部不可用。可选。
2 标识底层 bean 定义 (MessageTransformingHandler) 的 ID。此属性在 Chain 元素内部不可用。可选。
3 此端点的接收消息通道。此属性在 Chain 元素内部不可用。可选。
4 此 Claim Check 转换器使用的 MessageStore 引用。如果未指定,默认引用名为 messageStore 的 bean。可选。
5 指定此端点作为通道的订阅者连接时的调用顺序。当该通道使用 failover 调度策略时,这尤其重要。当此端点本身是带有队列的通道的轮询消费者时,此属性无效。此属性在 Chain 元素内部不可用。可选。
6 标识此端点处理消息后发送消息的消息通道。此属性在 Chain 元素内部不可用。可选。
7 如果设置为 true,此转换器将从 MessageStore 中移除消息。当消息只能被“Claim”一次时,此设置很有用。默认为 false。可选。
8 指定将回复消息发送到输出通道时等待的最长时间(毫秒)。默认为 30 秒。此属性在 Chain 元素内部不可用。可选。
9 定义一个轮询器。此元素在 Chain 元素内部不可用。可选。

Claim Once

有时,特定消息只能被 Claim 一次。作为一个类比,考虑处理飞机行李的过程。您在出发时托运行李并在抵达时提取行李。一旦行李被提取,如果未重新办理托运手续,就不能再次提取。为了适应这种情况,我们在 claim-check-out 转换器上引入了一个布尔属性 remove-message。此属性默认为 false。但是,如果设置为 true,Claim 的消息将从 MessageStore 中移除,以便不能再次 Claim。

此功能对存储空间有影响,特别是在基于内存 MapSimpleMessageStore 的情况下,未能移除消息最终可能导致 OutOfMemoryException。因此,如果您不期望进行多次 Claim,我们建议您将 remove-message 属性的值设置为 true。以下示例展示了如何使用 remove-message 属性

<int:claim-check-out id="checkout"
        input-channel="checkoutChannel"
        message-store="testMessageStore"
        output-channel="output"
        remove-message="true"/>

关于消息存储的说明

虽然我们很少关心 Claim Checks 的细节(只要它们工作即可),但您应该知道,Spring Integration 中实际 Claim Check(指针)的当前实现使用 UUID 来确保唯一性。

org.springframework.integration.store.MessageStore 是用于存储和检索消息的策略接口。Spring Integration 提供了两种方便的实现

  • SimpleMessageStore:一个基于内存 Map 的实现(默认,适用于测试)

  • JdbcMessageStore:一个使用 JDBC 通过关系型数据库的实现