|
对于最新稳定版本,请使用Spring AMQP 4.0.0! |
异常处理
许多使用 RabbitMQ Java 客户端的作可以抛出已检查异常。
例如,有很多情况下IOException实例可能会被抛出。
这兔子模板,SimpleMessageListenerContainer,以及其他Spring AMQP组件捕捉这些异常并将其转换为其中一个例外Amqp例外等级制度。
这些定义在“org.springframework.amqp”包中,Amqp例外是层级结构的基础。
当监听者抛出异常时,会被包裹在ListenerExecutionFailedException.
通常消息会被代理拒绝并重新排队。
设置defaultRequeueRejected自false导致消息被丢弃(或转发到死信交换)。
正如在《消息监听器和异步情况》中讨论的,监听者可以抛出AmqpRejectAndDontRequeueException(或ImmediateRequeueAmqpException)以有条件地控制这种行为。
然而,有一类错误是监听者无法控制行为的。
当遇到无法转换的消息(例如,无效的content_encoding部分异常在消息到达用户代码之前被抛出。
跟defaultRequeueRejected设置为true(默认)(或者扔出一个ImmediateRequeueAmqpException),此类消息会被反复重投。
在1.3.2版本之前,用户需要编写自定义文件错误处理程序如例外处理中所述,以避免这种情况。
从1.3.2版本开始,默认错误处理程序现在是条件拒绝错误处理它拒绝(且不重新排队)因无法恢复错误失败的消息。
具体来说,它会拒绝出现以下错误的失败消息:
-
O.S.AMQP......MessageConversionException:在使用以下条件转换接收消息负载时可以抛出消息转换器. -
O.S.消息......MessageConversionException:如果映射到某处时需要额外转换,转换服务可以抛出:@RabbitListener方法。 -
O.S.消息......方法参数非有效异常: 可以抛出,如果验证(例如,@Valid)在监听器中使用,验证失败。 -
O.S.消息......MethodArgumentTypeMismatchException如果入站消息被转换为不符合目标方法的类型,则可以抛出: 例如,参数被声明为消息<Foo>但Message<Bar(消息条>收到了。 -
java.lang.NoSuchMethodException:在1.6.3版本中添加。 -
java.lang.ClassCastException:在1.6.3版本中添加。
你可以用致命例外策略这样用户可以为条件消息拒绝提供自己的规则——例如,将代理实现给二进制异常分类器来自Spring Retry(消息监听者与异步情况)。
此外,ListenerExecutionFailedException现在有失败消息你可以用来做决定的财产。
如果FatalExceptionStrategy.isFatal()方法返回true,错误处理程序抛出AmqpRejectAndDontRequeueException.
默认致命例外策略当异常被判定为致命时,会记录警告消息。
自1.6.3版本起,将用户异常添加到致命列表的方便方法是子类条件拒绝错误处理程序。默认异常策略并覆盖isUserCauseFatal(可投掷原因)返回方法true对于致命例外情况。
处理DLQ消息的一个常见模式是设置生存时间对这些消息以及额外的DLQ配置,使这些消息过期并被路由回主队列重试。
这种技术的问题在于,导致致命异常的消息会无限循环。
从2.1版本开始,条件拒绝错误处理检测到X-死亡该邮件的头部导致一个致命异常被抛出。
消息会被记录并丢弃。
你可以通过设置discardFatalsWithXDeath属性条件拒绝错误处理自false.
从2.1.9版本开始,包含这些致命异常的消息默认被拒绝且不会重新排队,即使容器确认模式是手动的。
这些例外通常发生在监听器被调用之前,这样监听者就没有机会对消息进行ack或nack,使其在队列中保持未确认状态。
要恢复到之前的行为,请设置rejectManual属性条件拒绝错误处理自false. |