简体   繁体   English

在 Spring 集成中用于持久性传递到 AMQP 代理的消息存储

[英]Message store for persistence delivering to AMQP broker in Spring Integration

I'm trying to build integration flow, which will prevent the loss of messages during delivery to AMQP broker (rabbitMQ).我正在尝试构建集成流,这将防止消息在传递到 AMQP 代理(rabbitMQ)期间丢失。 In the case of broker stopping, I see some unexpected for me behavior:在经纪人停止的情况下,我看到了一些意想不到的行为:

  1. Failed messages are saving to the message store, but not for long.失败的消息正在保存到消息存储中,但不会保存很长时间。 This flow isn't waiting for broker availability, it extracts messages from messages store even the broker still be stopped此流程不等待代理可用性,即使代理仍然停止,它也会从消息存储中提取消息
  2. In case of successful restarting of rabbitmq, records from the message-store(if they still are presented) are not be delivered to the queue.如果 rabbitmq 成功重新启动,来自消息存储的记录(如果它们仍然存在)不会传递到队列。

Please help me in investigations.请帮助我进行调查。 Code Example:代码示例:

 @Bean
public MessageChannel messageStoreBackedChannel() {
    return new QueueChannel(
            new MessageGroupQueue(jdbcChannelMessageStore(), "Group_ID")
    );
}

 @Bean
public IntegrationFlow someFlow() {
    return IntegrationFlows
            .from("messageStoreBackedChannel")
            .channel("amqpMessageChannel")
            .get();
}

@Bean
public IntegrationFlow jmsExtractFlow(EntityManagerFactory entityManagerFactory) {
    return IntegrationFlows
            .from("amqpMessageChannel")
            .handle(message -> System.out.println(message.getPayload()))
            .get();
}


@Bean
public MessageChannel amqpMessageChannel() {
    return new PollableAmqpChannel("amqpMessageChannel", amqpTemplate);
}

@Bean
public JdbcChannelMessageStore jdbcChannelMessageStore() {
    var jdbcChannelMessageStore = new JdbcChannelMessageStore(dataSource);
    jdbcChannelMessageStore.setChannelMessageStoreQueryProvider(new PostgresChannelMessageStoreQueryProvider());

    return jdbcChannelMessageStore;
}

@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata defaultPoller() {
    PollerMetadata pollerMetadata = new PollerMetadata();
    pollerMetadata.setTrigger(new PeriodicTrigger(10));
    return pollerMetadata;
}

Consider to configure an endpoint in between your .from("messageStoreBackedChannel").channel("amqpMessageChannel") as transactional() .考虑将.from("messageStoreBackedChannel").channel("amqpMessageChannel")之间的端点配置为transactional()

Something like this:像这样的东西:

.from("messageStoreBackedChannel")
.bridge(e -> e.poller(p -> p.fixedDelay(10).transactional()))
.channel("amqpMessageChannel")

So, whenever delivery to the amqpMessageChannel fails, a transaction is going to roll back and the failed message will come back to the store until the next poll.因此,每当传递到amqpMessageChannel失败时,事务将回滚,失败的消息将返回到存储区,直到下一次轮询。

Of course you can stop that bridge endpoint when you get an error connecting to RabbitMQ.当然,当您在连接到 RabbitMQ 时遇到错误时,您可以停止该bridge端点。 But how can you determine then that connection comes back?..但是你怎么能确定那个连接又回来了呢?...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM