Reputation: 2291
I have a spring rabbit consumer:
public class SlackIdle1Consumer extends AbstractMessageConsumer {
@Override public void process(Message amqpMessage, Channel channel)
throws Exception {
/*very bad exception goes here.
it causes amqp message to be rejected and if no other consumer is available and error
still persists, the message begins looping over and over.
And when the error is fixed,
those messages are being processed but the result of this procession may be harmful.
*/
}
}
}
And somewhere inside an exception happens. Lets imagine this is a bad exception - development logic error. So amqp message begins to spin indefinitely, and when error is fixed and consumer restarted, all old messages are being processed, and it's bad, because logic and data may change since those messages were sent. How to handle it properly?
So the question is: how to fix this situation properly? Should I wrap all my code to try-catch clause or will I have to develop 'checks' in each consumer to prevent consistency issues in my app?
Upvotes: 1
Views: 848
Reputation: 174484
There are several options:
Set the container's defaultRequeueRejected
property to false
so failed messages are always rejected (discarded or sent to a dead letter exchange depending on queue configuration).
If you want some exceptions to be retried and others not, then add a try catch and throw an AmqpRejectAndDontRequeueException
to reject those you don't want retried.
Add a custom ErrorHandler
to the container, to do the same thing as #2 - determine which exceptions you want retried - documentation here.
Add a retry advice with a recoverer - the default recoverer simply logs the error, the RejectAndDontRequeueRecoverer
causes the message to be rejected after retries are exhausted, the RepublishMessageRecoverer
is used to write to a queue with additional diagnostics in headers - documentation here.
Upvotes: 3