此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring AMQP 3.2.0spring-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()method 返回true,错误处理程序会抛出AmqpRejectAndDontRequeueException. 默认的FatalExceptionStrategy在确定异常为致命异常时记录警告消息。spring-doc.cadn.net.cn

从 1.6.3 版本开始,将 user exceptions 添加到 fatal list 的一种便捷方法是 subclassConditionalRejectingErrorHandler.DefaultExceptionStrategy并覆盖isUserCauseFatal(Throwable cause)method 返回true对于致命异常。spring-doc.cadn.net.cn

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

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