排他使用者失败时要处理哪个AmqpEvent或AmqpException

时间:2019-02-21 19:09:59

标签: spring spring-boot spring-amqp spring-rabbitmq spring-rabbit

我有同一应用程序的两个实例,它们在不同的虚拟机中运行。我想为其中一个的使用者授予对队列的独占访问权限,同时使另一个使用者所使用的本地缓存无效。

现在,我已经确定我需要处理ListenerContainerConsumerFailedEvent,但是我猜想为此事件实现ApplicationListener并不能确保我是由于独家消费者而收到此事件例外。我可能想检查事件的Throwable,或进一步检查事件。

AmqpException的哪个子类,或者应该执行哪些进一步的检查以确保由于专有的消费者访问而收到异常?

1 个答案:

答案 0 :(得分:1)

侦听器容器实现中的逻辑如下:

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) {