我有一只春兔消费者:
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.
*/
}
}
}
异常发生在某个地方。让我们想象这是一个错误的例外 - 开发逻辑错误。所以amqp消息开始无限期地旋转,并且当错误被修复并且消费者重新启动时,所有旧消息都被处理,并且它是坏的,因为逻辑和数据可能会发生变化,因为这些消息被发送。如何妥善处理?
所以问题是:如何正确解决这种情况?我应该将我的所有代码都包装到try-catch子句中,还是我必须开发'检查'在每个消费者中,以防止我的应用程序出现一致性问题?
答案 0 :(得分:3)
有几种选择:
将容器的defaultRequeueRejected
属性设置为false
,以便始终拒绝失败的消息(丢弃或根据队列配置发送到死信交换)。
如果你想要重试一些例外而不是其他例外,那么添加一个try catch并抛出一个AmqpRejectAndDontRequeueException
来拒绝你不想重试的那些。
向容器添加自定义ErrorHandler
,与#2执行相同的操作 - 确定要重试的例外情况 - documentation here。
使用recoverer添加重试建议 - 默认的recoverer只记录错误,RejectAndDontRequeueRecoverer
导致在重试耗尽后拒绝消息,RepublishMessageRecoverer
用于写入标题中包含其他诊断的队列 - documentation here。