首先,我介绍我的情况的上下文:
我正在使用spring-boot
和spring-rabbitmq
。 它正在为我工作,您应该知道我必须为收到的消息实现自定义转换器。
(1)从这个转换器可以抛出异常,例如在不正确的消息等情况下。
(2)转换成功后(无异常),调用监听器。 然后,在侦听器中也可以抛出异常。
现在,我想强制两件事:
(1')在转换器中出现过期时不要重新排队消息。 简单地说,向队列发送确认并模拟一切正常。
(2')在这种情况下,默认设置是什么?当内部spring-rabbitmq engine
决定向队列发送确认时?当它决定命令重新排队时? 是否可以根据情况进行管理?
我在文档中发现:
如果未启用重试并且侦听器引发异常,则由 默认情况下,将无限期重试传递。您可以修改此 行为有两种方式;将默认重新排队已拒绝属性设置为 false 并且将尝试零重新交付;或者,抛出一个 AmqpRejectAndDontRequeueException 以指示消息应该是 拒绝。这是启用重试时使用的机制,并且 达到最大传递尝试次数。
例如,在依赖于侦听器中捕获的异常中,我应该决定是否要重新排队消息,正如我认为的那样(只需从catch
AmqpRejectAndDontRequeueException
抛出)。 我不确定这是否是好方法,这就是为什么我问你的看法。
请阅读参考手册。
该行为(大部分)由ErrorHandler
控制。
抛出MessageConversionException
- 容器对大多数异常的消息重新排队,但某些异常被认为是致命的。通常,如果消息无法转换,那么重新传递它是没有意义的。
这一切都在称为异常处理的部分中(令人惊讶?)中得到了清晰的解释
从版本 1.3.2 开始,默认的错误处理程序现在是一个 ConditionalRejectingErrorHandler,它将拒绝(而不是重新排队)失败并出现不可恢复错误的消息:
o.s.amqp...消息转换异常
o.s.消息传递...消息转换异常
o.s.消息传递...MethodArgumentNotValidException
o.s.消息传递...方法参数类型不匹配异常
java.lang.NoSuchMethodException
java.lang.ClassCastException
第一个可以在使用消息转换器转换传入消息有效负载时引发。如果在映射到 @RabbitListener 方法时需要其他转换,则转换服务可能会引发第二个转换。如果在侦听器中使用验证(例如 @Valid)并且验证失败,则可能会抛出第三个。如果入站消息转换为目标方法不正确的类型,则可能会引发第四个。例如,参数声明为消息,但收到消息。
第五个和第六个是在 1.6.3 版中添加的。
您可以根据需要自定义ErrorHandler
。