简体   繁体   中英

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). 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.

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() .

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.

Of course you can stop that bridge endpoint when you get an error connecting to RabbitMQ. But how can you determine then that connection comes back?..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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