【问题标题】:Correlate messages between 2 JMS queues using Spring integration components使用 Spring 集成组件关联 2 个 JMS 队列之间的消息
【发布时间】:2019-03-22 12:05:46
【问题描述】:

我有 2 个 JMS 队列,我的应用程序使用 Jms.messageDrivenChannelAdapter(...) 组件订阅了这两个队列。

第一个队列接收Paid 类型的消息。第二个队列接收Reversal 类型的消息。

业务场景定义Paid类型消息和Reversal类型消息之间的关联。

Reversal 应该等待Paid 才能被处理。

如何使用 Spring Integration 实现这种“等待”模式?

是否可以在 2 个 JMS 队列之间关联消息?

【问题讨论】:

    标签: jms spring-integration spring-integration-dsl


    【解决方案1】:

    the documentation about the Aggregator

    聚合器使用某种关联策略关联消息,并根据某种发布策略释放组。

    聚合器通过关联和存储一组相关消息来组合它们,直到该组被认为是完整的。此时,聚合器通过处理整个组创建单个消息并将聚合消息作为输出发送。

    默认情况下,输出负载是分组消息负载的列表,但您可以提供自定义输出处理器。

    编辑

    @SpringBootApplication
    public class So55299268Application {
    
        public static void main(String[] args) {
            SpringApplication.run(So55299268Application.class, args);
        }
    
        @Bean
        public IntegrationFlow in1(ConnectionFactory connectionFactory) {
            return IntegrationFlows.from(Jms.messageDrivenChannelAdapter(connectionFactory)
                        .destination("queue1"))
                    .channel("aggregator.input")
                    .get();
        }
    
        @Bean
        public IntegrationFlow in2(ConnectionFactory connectionFactory) {
            return IntegrationFlows.from(Jms.messageDrivenChannelAdapter(connectionFactory)
                        .destination("queue2"))
                    .channel("aggregator.input")
                    .get();
        }
    
        @Bean
        public IntegrationFlow aggregator() {
            return f -> f
                    .aggregate(a -> a
                            .correlationExpression("headers.jms_correlationId")
                            .releaseExpression("size() == 2")
                            .expireGroupsUponCompletion(true)
                            .expireGroupsUponTimeout(true)
                            .groupTimeout(5_000L)
                            .discardChannel("discards.input"))
                    .handle(System.out::println);
        }
    
        @Bean
        public IntegrationFlow discards() {
            return f -> f.handle((p, h) -> {
                System.out.println("Aggregation timed out for " + p);
                return null;
            });
        }
    
        @Bean
        public ApplicationRunner runner(JmsTemplate template) {
            return args -> {
                send(template, "one", "two");
                send(template, "three", null);
            };
        }
    
        private void send(JmsTemplate template, String one, String two) {
            template.convertAndSend("queue1", one, m -> {
                m.setJMSCorrelationID(one);
                return m;
            });
            if (two != null) {
                template.convertAndSend("queue2", two, m -> {
                    m.setJMSCorrelationID(one);
                    return m;
                });
            }
        }
    
    }
    

    GenericMessage [payload=[two, one], headers={jms_redelivered=false, jms_destination=queue://queue1, jms_correlationId=one, id=784535fe-8861-1b22-2cfa-cc2e67763674, priority=4, jms_timestamp= 1553290921442, jms_messageId=ID:Gollum2.local-55540-1553290921241-4:1:3:1:1, 时间戳=1553290921457}]

    2019-03-22 17:42:06.460 INFO 55396 --- [ask-scheduler-1] o.s.i.a.AggregatingMessageHandler : 带有相关键 [三] 的消息组到期

    聚合超时三个

    【讨论】:

    • 非常感谢您的回答。是否有任何代码示例展示了聚合器​​的实际应用?
    • 我在答案中添加了一个简单的例子;聚合器有很多属性,因此您应该探索它们以满足您的需求。
    • 非常感谢这个例子。如果我想关联自收到Reversal 1 周后出现Paid 事务的消息怎么办?似乎我需要将其保存到数据库中,并在我想要关联时检索记录。
    • 是的;见.messageStore(...)。该框架提供了number of store implementations, including JDBC
    猜你喜欢
    • 2011-10-01
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 2013-02-26
    • 1970-01-01
    • 2010-11-05
    • 2018-05-27
    相关资源
    最近更新 更多