Persistent retries in Apache Camel

Viewed 1259

I am struggling with making it possible to persist messages for redeliveries in Camel:

from("activemq:incoming-queue")
     .errorHandler(
         deadLetterChannel("activemq:queue.dead-letter")
         .maximumRedeliveries(100)
         .redeliveryDelay(TimeUnit.SECONDS.toMillis(10))
     )
.to("http4://example.com")

In the event of failure a retry is scheduled and if we shut down Camel it puts messages back in the ActiveMQ queue which is good.

The thing is that if you kill it with "kill -9" messages will be lost forever since Camel holds them in memory during the retries.

The question is how to guarantee that messages won't be lost on retries even in the case of a sudden outage of the system?

UPDATE:

We implemented guaranteed redelivery using transactions:

    @Bean
    public JmsTransactionManager jmsTransactionManager(ConnectionFactory connectionFactory) {
        JmsTransactionManager jmsTransactionManager = new JmsTransactionManager();
        jmsTransactionManager.setConnectionFactory(connectionFactory);

        return jmsTransactionManager;
    }

    /**
     * Disables ActiveMQ redelivery since it clashes with camel redelivery system
     */
    @Bean
    public RedeliveryPolicy redeliveryPolicy(ActiveMQConnectionFactory connectionFactory) {
        RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
        redeliveryPolicy.setMaximumRedeliveries(0);
        connectionFactory.setRedeliveryPolicy(redeliveryPolicy);
        return redeliveryPolicy;
    }

Then the route looks as shown below (note the transacted=true parameter, for some reasons .transacted() method behavies differently):

from("activemq:incoming-queue?transacted=true")
         .errorHandler(
             deadLetterChannel("activemq:queue.dead-letter")
             .maximumRedeliveries(100)
             .redeliveryDelay(TimeUnit.SECONDS.toMillis(10))
         )
.to("http4://example.com")

Are there any disadvantages using this approach?

2 Answers
Related