我确实阅读了此参考资料:https : //www.rabbitmq.com/dlx.html,但是它并不能解决我的疑问,即: 在接受消息的情况下没有问题- spring-rabbitmq发送ack并且一切都很好,DLX不是吗?不知道确认的消息。
spring-rabbitmq
DLX
问题是万一拒绝答案,那该怎么扔MessageConverterException?此消息已删除或移至DLX?
MessageConverterException
如果还有其他例外情况呢?例如Exception?它已被删除/重新排队/移至DLX?
Exception
我想 在@Gary的答案之后进行编辑, 我认为,在答案的@Gary之后,我应该添加有关我的案例的更多详细信息以及@Gary答案的一些摘要。@Gary完全掌握了我的用例。
我不希望重新排队-永不(我害怕循环),但我不想在抛出异常(例如,失去与数据库的连接)时丢失消息- 该消息应重新发送给DLX。另一方面,消息的转换应视为致命错误-不重新排队,不重新发送到DLX-只是永久删除消息。 通常,在依赖异常的情况下,拒绝(=如果配置,则返回DLX)或接受,从不重新排队。
总结一下@Gary提出的简单方法。 首先 :我们可以覆盖ExceptionHandler发送小节/小节的管理,这给了我们完全的控制权。 其次 :IMO更简单,解决方案是设置defaultRequeueRejected=false 并在转换器中抛出ImmediateAcknowledgeAmqpException。它使得RabbitMQ认为答案已被接受(与第一种解决方案的情况相同),而且不会调用侦听器。 **Conclusion**: UsingInstantAcknowledgeAmqpException orExceptionHandler`异常,我们可以完全控制永久拒绝消息(处于高级确认状态)并重新发送到DLX。
ExceptionHandler
defaultRequeueRejected=false
ImmediateAcknowledgeAmqpException
RabbitMQ
**Conclusion**: Using
or
RabbitMQ对异常一无所知。
当容器捕获异常时,它将调用channel.basicReject(deliveryTag, requeue)。
channel.basicReject(deliveryTag, requeue)
如果requeue为true,则重新排队该消息。
默认情况下,除此处提到的例外外
osamqp … MessageConversionException osmessaging … MessageConversionException osmessaging … MethodArgumentNotValidException osmessaging … MethodArgumentTypeMismatchException java.lang.NoSuchMethodException java.lang.ClassCastException
osamqp … MessageConversionException
osmessaging … MessageConversionException
osmessaging … MethodArgumentNotValidException
osmessaging … MethodArgumentTypeMismatchException
java.lang.NoSuchMethodException
java.lang.ClassCastException
requeue 设置为true,因此将消息重新排队。
requeue
对于这些例外,认为传递是致命的,并且不重新排队该消息,如果配置了该消息,它将进入DLX / DLQ。
容器有一个defaultRequeueRejected默认为true 的标志;如果设置为false; 没有例外将被重新排队。
defaultRequeueRejected
false
对于应用程序级异常,通常,消息将重新排队。要动态拒绝(而不是重新排队)消息,请确保AmqpRejectAndDontRequeueException原因链中有一个。这指示容器不要重新排队该消息,它将转到DLX / DLQ(如果已配置)。通过上述defaultRequeueRejected标志启用此行为。
AmqpRejectAndDontRequeueException
所有这些都在文档中进行了解释,正如我在其他回答中所讨论的那样,您可以使用自定义错误处理程序来更改此行为。文档中也对此进行了说明。
无法向DLX / DLQ发送某些例外,而不能发送其他例外。rabbit仅具有二进制选项,可以重新排队,也可以不重新排队;对于后者,如果配置了DLX / DLQ,则所有此类拒绝的消息都将进入DLX / DLQ。
Spring AMQP提供了另一个例外ImmediateAcknowledgeAmqpException。如果您的听众抛出此异常,则该消息将被确认为成功处理(channel.basicAck())。这是容器提供的唯一技术,用于丢弃错误消息而不将其发送到DLX / DLQ。
channel.basicAck()
当然,您的应用程序本身可以丢弃此类消息。
如果要对所有业务异常进行DLX / DLQ,但要放弃转换异常,则抛出AmqpRejectAndDontRequeueException(或设置defaultRequeueRejected为false),然后ImmediateAcknowledgeAmqpException从转换器中抛出。