我有两个在不同虚拟机中运行的同一应用程序的实例。我想为其中一个的消费者提供独家访问队列的独家访问,同时使消费者使用的本地缓存无效。
现在,我已经弄清楚我需要处理ListenerContainerConsumerFailedEvent
,但是我猜想,为此事件实施ApplicationListener
不会确保由于独家消费者的例外,我会收到此事件。我可能想检查事件的Throwable
或事件进一步检查。
AmqpException
的哪个子类或我应该执行什么进一步检查以确保由于独家消费者访问而收到例外?
侦听器容器实现中的逻辑是这样的:
if (e.getCause() instanceof ShutdownSignalException
&& e.getCause().getMessage().contains("in exclusive use")) {
getExclusiveConsumerExceptionLogger().log(logger,
"Exclusive consumer failure", e.getCause());
publishConsumerFailedEvent("Consumer raised exception, attempting restart", false, e);
}
因此,我们确实提出了一个ListenerContainerConsumerFailedEvent
事件,您可以像在框架中一样跟踪原因消息,但另一方面,您可以只注入您自己的ConditionalExceptionLogger
:
/**
* Set a {@link ConditionalExceptionLogger} for logging exclusive consumer failures. The
* default is to log such failures at WARN level.
* @param exclusiveConsumerExceptionLogger the conditional exception logger.
* @since 1.5
*/
public void setExclusiveConsumerExceptionLogger(ConditionalExceptionLogger exclusiveConsumerExceptionLogger) {
并在那捕捉到这样的独家情况。
您也可以考虑在代码中使用RabbitUtils.isExclusiveUseChannelClose(cause)
:
/**
* Return true if the {@link ShutdownSignalException} reason is AMQP.Channel.Close
* and the operation that failed was basicConsumer and the failure text contains
* "exclusive".
* @param sig the exception.
* @return true if the declaration failed because of an exclusive queue.
*/
public static boolean isExclusiveUseChannelClose(ShutdownSignalException sig) {