We are implementing a solution using Apache Camel with Spring Boot. Our requirement is to configure the system to retry failed events for a specified number of iterations before routing them to a Dead Letter Queue (DLQ).
However, we are encountering an issue where, during the retry process, it appears that the main queue consumer is being blocked. As a result, new events are either not being consumed or are being discarded.
We have configured exception handling and retry mechanisms as follows:
Need guidance on how to address this issue or suggest potential solutions to ensure that new events continue to be processed while retrying the failed events?
onException(ReplayableException.class)
.asyncDelayedRedelivery()
.maximumRedeliveries(5) // Retry
.redeliveryDelay(2L *1000) // Delay between retries (in milliseconds)
.maximumRedeliveryDelay(16L* 60L *1000) // Maximum delay between retries
.backOffMultiplier(2)
.handled(true) // Mark the exception as handled
.to(getDLQRoute())
.log("Exception handled: ${exception.message}, message sent to DLQ")
.logExhaustedMessageHistory(true)
.end();
how to address this issue or suggest potential solutions to ensure that new events continue to be processed while retrying the failed events?
1
The reason why new events aren’t processed it’s because main consumer is blocked.
To fix it, you need to scale or have multiple consumers,or concurrent consumers.
As for the error handler where you have your deadletter channel.
from("jms:queue:mainQueue?concurrentConsumers=5")
.routeId("mainRoute")
.onException(ReplayableException.class)
.errorHandler(buildErrorHandlerDlc (getPointsToRewardDLQ()))
and buildErrorHandlerDlc would be like :
return deadLetterChannel(dlc)
.retryAttemptedLogLevel(LoggingLevel.ERROR)
.logRetryStackTrace(true)
.useOriginalMessage()
.onPrepareFailure(this::doSomething);