此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring AMQP 3.2.6spring-doc.cadn.net.cn

异常处理

RabbitMQ Java 客户端的许多作可能会抛出已检查的异常。 例如,有很多情况下IOException实例可能会被抛出。 这RabbitTemplate,SimpleMessageListenerContainer,其他 Spring AMQP 组件捕获这些异常并将它们转换为AmqpException等级制度。 这些是在 'org.springframework.amqp' 包中定义的,并且AmqpException是层次结构的基础。spring-doc.cadn.net.cn

当侦听器抛出异常时,它会包装在ListenerExecutionFailedException. 通常,消息会被代理拒绝并重新排队。 设置defaultRequeueRejectedfalse导致消息被丢弃(或路由到死信交换)。 如消息侦听器和异步情况中所述,侦听器可以抛出AmqpRejectAndDontRequeueException(或ImmediateRequeueAmqpException) 有条件地控制此行为。spring-doc.cadn.net.cn

但是,有一类错误,侦听器无法控制行为。 当遇到无法转换的消息(例如,无效的content_encodingheader),在消息到达用户代码之前会抛出一些异常。 跟defaultRequeueRejected设置为true(默认)(或抛出一个ImmediateRequeueAmqpException),此类消息将一遍又一遍地重新传递。 在 1.3.2 版本之前,用户需要编写自定义ErrorHandler,如异常处理中所述,以避免这种情况。spring-doc.cadn.net.cn

从 1.3.2 版开始,默认的ErrorHandler现在是一个ConditionalRejectingErrorHandler拒绝(并且不重新排队)失败并出现不可恢复错误的消息。 具体来说,它拒绝失败并出现以下错误的消息:spring-doc.cadn.net.cn

  • o.s.amqp…​MessageConversionException:在使用MessageConverter.spring-doc.cadn.net.cn

  • o.s.messaging…​MessageConversionException:如果映射到@RabbitListener方法。spring-doc.cadn.net.cn

  • o.s.messaging…​MethodArgumentNotValidException:如果验证(例如,@Valid) 在侦听器中使用,验证失败。spring-doc.cadn.net.cn

  • o.s.messaging…​MethodArgumentTypeMismatchException:如果入站消息转换为目标方法不正确的类型,则可以引发。 例如,该参数声明为Message<Foo>Message<Bar>收到。spring-doc.cadn.net.cn

  • java.lang.NoSuchMethodException:在 1.6.3 版本中添加。spring-doc.cadn.net.cn

  • java.lang.ClassCastException:在 1.6.3 版本中添加。spring-doc.cadn.net.cn

您可以使用FatalExceptionStrategy以便用户可以提供自己的条件消息拒绝规则,例如,将委托实现用于BinaryExceptionClassifier来自 Spring Retry(消息侦听器和异步情况)。 此外,ListenerExecutionFailedException现在有一个failedMessage可在决策中使用的属性。 如果FatalExceptionStrategy.isFatal()方法返回true,错误处理程序会抛出AmqpRejectAndDontRequeueException. 默认值FatalExceptionStrategy当异常被确定为致命异常时,记录警告消息。spring-doc.cadn.net.cn

从版本 1.6.3 开始,将用户异常添加到致命列表的一种便捷方法是将子类ConditionalRejectingErrorHandler.DefaultExceptionStrategy并覆盖isUserCauseFatal(Throwable cause)返回的方法true对于致命的例外。spring-doc.cadn.net.cn

处理 DLQ 消息的常见模式是将time-to-live这些消息以及其他 DLQ 配置,以便这些消息过期并路由回主队列进行重试。 这种技术的问题在于,导致致命异常的消息会永远循环。 从 2.1 版开始,ConditionalRejectingErrorHandler检测到x-death导致引发致命异常的消息的标头。 该消息将被记录并丢弃。 您可以通过将discardFatalsWithXDeath属性ConditionalRejectingErrorHandlerfalse.spring-doc.cadn.net.cn

从版本 2.1.9 开始,默认情况下,即使容器确认模式为 MANUAL,具有这些致命异常的消息也会被拒绝并且不会重新排队。 这些异常通常发生在调用侦听器之前,因此侦听器没有机会确认或确认消息,因此它以未确认状态保留在队列中。 要恢复到以前的行为,请将rejectManual属性ConditionalRejectingErrorHandlerfalse.