无法获得对锁定队列的独占访问权限
Posted
技术标签:
【中文标题】无法获得对锁定队列的独占访问权限【英文标题】: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.174: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.174:17959 -> 192.168.100.145:5671): connection_close_abruptly
=INFO REPORT==== 12-Apr-2016::15:13:41 === 接受 AMQP 连接 (XX.XXX.57.174:51716 -> 192.168.100.145:5671)
我无法重现它(我尝试关闭rabbitmq的连接并移除网线,但应用程序再次连接良好),所以我不知道为什么会发生这种情况。 假设私有队列和独占队列随着连接的关闭而被删除,那么为什么会发生这种情况呢?如何捕获此异常并从中恢复?
谢谢
【问题讨论】:
【参考方案1】:你是对的,独占队列在声明它的连接时被删除;这意味着该连接仍处于打开状态,并且您在日志中看到的连接并未声明它。
当您的系统处于这种状态时,请转到管理 UI,您可以在其中探索队列以及哪个连接拥有它。
例如Exclusive owner 127.0.0.1:60113
如果显示连接已关闭(上例中为 XX.XXX.57.174:17959),您应该联系 rabbitmq-users google 组中的 rabbitmq 人员,这似乎不是 spring-amqp 问题;
编辑
仅供参考,如果被动队列声明因任何原因失败,默认情况下,消费者将以 5 秒的间隔尝试 3 次,然后放弃并停止容器。
容器上有两个属性可用于调整此值 - declarationRetries
和 failedDeclarationRetryInterval
(分别默认为 3 和 5000)。如果您使用<rabbit:listener-container />
配置,则命名空间上有等效的属性。
【讨论】:
谢谢,我会问rabbitmq的家伙。以及如何检测到此错误以显示错误消息? 我不确定你的意思;容器已经记录了此类错误。从 1.5 版开始,您可以将ApplicationListener<ListenerContainerConsumerFailedEvent>
bean 添加到上下文中,以在消费者因任何原因无法启动时接收事件。
我在该项目中有 1.4.4.RELEASE 版本,是否有其他选项可以接收事件并将其显示给用户?
不,只是日志消息。
我找到了一种重现问题的方法:更改网络。如果你是通过wifi连接的,然后切换到另一个wifi,那么连接会恢复,但是旧连接需要时间才能消失,所以在创建第二个连接时,私有队列仍然存在,因此应用程序无法订阅它们新连接。【参考方案2】:
检查队列名称不应与交换绑定,否则您将收到此错误。或者我认为队列名称已经存在。
【讨论】:
以上是关于无法获得对锁定队列的独占访问权限的主要内容,如果未能解决你的问题,请参考以下文章
ASP网页制作中,在连接Access数据库时,总是出现数据库被以独占方式打开,或者是没有访问权限