对于最新的稳定版本,请使用 Spring AMQP 3.2.0spring-doc.cn

异常处理

使用 RabbitMQ Java 客户端的许多操作可能会引发检查异常。 例如,在很多情况下可能会引发实例。 , , 和其他 Spring AMQP 组件捕获这些异常,并将它们转换为层次结构中的异常之一。 这些是在'org.springframework.amqp'包中定义的,并且是层次结构的基础。IOExceptionRabbitTemplateSimpleMessageListenerContainerAmqpExceptionAmqpExceptionspring-doc.cn

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

但是,有一类错误是侦听器无法控制行为的。 当遇到无法转换的消息(例如,无效的 header)时,会在消息到达用户代码之前引发一些异常。 设置为 (default) (或throwing an )后,此类消息将一遍又一遍地重新传递。 在版本 1.3.2 之前,用户需要编写自定义 ,如 异常处理 中所述,以避免这种情况。content_encodingdefaultRequeueRejectedtrueImmediateRequeueAmqpExceptionErrorHandlerspring-doc.cn

从版本 1.3.2 开始,现在的默认值是 a,它拒绝(并且不会重新排队)因不可恢复的错误而失败的消息。 具体而言,它会拒绝失败并显示以下错误的消息:ErrorHandlerConditionalRejectingErrorHandlerspring-doc.cn

  • o.s.amqp…​MessageConversionException:在使用 .MessageConverterspring-doc.cn

  • o.s.messaging…​MessageConversionException:如果在映射到方法时需要额外的转换,则转换服务可以引发此消息。@RabbitListenerspring-doc.cn

  • o.s.messaging…​MethodArgumentNotValidException:如果在侦听器中使用了验证(例如 ),并且验证失败,则可以引发。@Validspring-doc.cn

  • o.s.messaging…​MethodArgumentTypeMismatchException:如果入站消息已转换为不适合目标方法的类型,则可能会引发此错误。 例如,参数声明为 but is received。Message<Foo>Message<Bar>spring-doc.cn

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

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

你可以使用 a 配置此错误处理程序的实例,以便用户可以为条件消息拒绝提供自己的规则 - 例如,从 Spring 重试(消息侦听器和异步情况)的委托实现。 此外,现在还有一个可在决策中使用的属性。 如果该方法返回 ,则错误处理程序将引发 . 默认情况下,当异常被确定为致命异常时,将记录一条警告消息。FatalExceptionStrategyBinaryExceptionClassifierListenerExecutionFailedExceptionfailedMessageFatalExceptionStrategy.isFatal()trueAmqpRejectAndDontRequeueExceptionFatalExceptionStrategyspring-doc.cn

从版本 1.6.3 开始,将用户异常添加到致命列表的一种便捷方法是 subclass 并覆盖该方法以返回致命异常。ConditionalRejectingErrorHandler.DefaultExceptionStrategyisUserCauseFatal(Throwable cause)truespring-doc.cn

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

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