【问题标题】:Cannot obtain exclusive access to locked queue无法获得对锁定队列的独占访问权限
【发布时间】:2016-08-05 21:41:02
【问题描述】:

我有一个这样定义的匿名和独占队列:

@Bean 
    public SimpleMessageListenerContainer responseMessageListenerContainer(){
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(simpleRoutingConnectionFactory());
        container.setQueues(responseAnonymousQueue());
        container.setMessageListener(rabbitTemplate());
        container.setAcknowledgeMode(AcknowledgeMode.AUTO);
        container.setMessageConverter(jsonMessageConverter());
        return container;
    }

@Bean
    public Queue responseAnonymousQueue() { 
        return new MyAnonymousQueue();
    }

有时我会在 rabbitmq 日志中收到此错误:

=错误报告==== 2016 年 4 月 12 日::15:13:42 === 连接 时出现通道错误 (XX.XXX.57.1​​74:51716 -> 192.168.100.145:5671, 虚拟主机:'/',用户:'XXXX_USER'),频道 1: {amqp_error,resource_locked, “无法在 vhost '/' 中获得对锁定队列 'XXXX_USER-broad-1457bb43-6487-4252-b21a-a5a92d19e0dc' 的独占访问权限”, 'queue.declare'}

所以客户端无法声明队列,也无法接收来自 AMQP 服务器的消息。

它发生在这条消息之后:

=警告报告==== 2016 年 4 月 12 日::15:11:51 === 关闭 AMQP 连接 (XX.XXX.57.1​​74:17959 -> 192.168.100.145:5671): connection_close_abruptly

=INFO REPORT==== 12-Apr-2016::15:13:41 === 接受 AMQP 连接 (XX.XXX.57.1​​74:51716 -> 192.168.100.145:5671)

我无法重现它(我尝试关闭rabbitmq的连接并移除网线,但应用程序再次连接良好),所以我不知道为什么会发生这种情况。 假设私有队列和独占队列随着连接的关闭而被删除,那么为什么会发生这种情况呢?如何捕获此异常并从中恢复?

谢谢

【问题讨论】:

    标签: spring spring-amqp


    【解决方案1】:

    你是对的,独占队列在声明它的连接时被删除;这意味着该连接仍处于打开状态,并且您在日志中看到的连接并未声明它。

    当您的系统处于这种状态时,请转到管理 UI,您可以在其中探索队列以及哪个连接拥有它。

    例如Exclusive owner 127.0.0.1:60113

    如果显示连接已关闭(上例中为 XX.XXX.57.1​​74:17959),您应该联系 rabbitmq-users google 组中的 rabbitmq 人员,这似乎不是 spring-amqp 问题;

    编辑

    仅供参考,如果被动队列声明因任何原因失败,默认情况下,消费者将以 5 秒的间隔尝试 3 次,然后放弃并停止容器。

    容器上有两个属性可用于调整此值 - declarationRetriesfailedDeclarationRetryInterval(分别默认为 3 和 5000)。如果您使用<rabbit:listener-container /> 配置,则命名空间上有等效的属性。

    【讨论】:

    • 谢谢,我会问rabbitmq的家伙。以及如何检测到此错误以显示错误消息?
    • 我不确定你的意思;容器已经记录了此类错误。从 1.5 版开始,您可以将 ApplicationListener<ListenerContainerConsumerFailedEvent> bean 添加到上下文中,以在消费者因任何原因无法启动时接收事件。
    • 我在该项目中有 1.4.4.RELEASE 版本,是否有其他选项可以接收事件并将其显示给用户?
    • 不,只是日志消息。
    • 我找到了一种重现问题的方法:更改网络。如果你是通过wifi连接的,然后切换到另一个wifi,那么连接会恢复,但是旧连接需要时间才能消失,所以在创建第二个连接时,私有队列仍然存在,因此应用程序无法订阅它们新连接。
    【解决方案2】:

    检查队列名称不应与交换绑定,否则您将收到此错误。或者我认为队列名称已经存在。

    【讨论】:

      猜你喜欢
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 2013-10-22
      • 2016-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多