没有连接的AMQP/RabbitMQ通道何时会失效?

9
我有一个简单的RabbitMQ测试程序,随机将消息加入队列,另一个程序则读取这些消息,两个程序都使用Spring-AMQP。如果消费者死亡(例如杀死进程而没有机会关闭它的连接或通道),任何未被确认的消息似乎会一直保持未确认状态。
我看到了许多参考文献(例如这个问题),称当频道没有连接时,该频道将死亡,并且仍未确认的消息将被重新传递。这不是我看到的行为-相反,我得到了一个越来越长的标记为空闲的通道列表和一个越来越长的标记为正在运行但没有活动的连接列表。
是否需要某些配置才能在进程被杀死后注意到连接已经关闭?
编辑: 我在VirtualBox VM中运行rabbitmq服务器,这显然不能正确地管理NAT上的死入站连接。直接在物理主机上运行mq服务器就可以正常工作。

1
顺便提一句:我遇到了类似的问题,也就是当独占式消费者死亡后,独占队列不能及时地在代理中清理。这导致那些具有确定性名称的组件无法启动。将 ConnectionFactory.RequestedHeartbeat 设置为较小的值(以秒为单位)解决了此问题。 - drstevens
2个回答

4

AMQP使用队列和交换机。您可以在交换机上发布消息,并将队列绑定到交换机以获取消息(您可以在我的博客中看到简短的解释)。创建队列时,您可以设置它自动删除以及在自动删除之前多久未使用它。

queue.declare(short reserved-1, queue-name queue, bit passive, bit durable, bit exclusive, bit auto-delete, no-wait no-wait, table arguments) ➔ declare-ok

支持:full Declare queue,如果需要则创建。

此方法创建或检查队列。当创建新队列时,客户端可以指定各种属性,以控制队列及其内容的耐久性以及队列的共享级别。

RabbitMQ实现了AMQP规范的扩展,允许队列的创建者控制其行为的各个方面。

每队消息TTL此扩展程序确定发布到队列的消息在被服务器丢弃之前可以存活多长时间。 TTL的时间是使用该方法的参数的x-message-ttl参数进行配置的。

队列过期队列可以声明具有可选租赁时间。租赁时间确定队列可以在未使用多长时间后由服务器自动删除。租赁时间作为参数提供给此方法的arguments参数中的x-expires参数。

镜像队列我们已经开发了队列的主/从高可用性。这通过允许在RabbitMQ集群中的其他节点上镜像队列来实现。结果是,如果集群的一个节点失败,则队列可以自动切换到其中一个镜像,并继续运行,而不会出现服务不可用的情况。要创建镜像队列,您需要在此方法的参数中提供x-ha-policy参数。


我不想删除队列,我希望它是持久的。但我也希望未被确认的消息(由于进程在确认之前死亡而被消耗)能够重新传递。需要删除的是已经死亡的连接/通道,而不是消息。 - Joe Kearney
2
好的,现在我明白了 - 你需要创建一个ConnectionParameters实例并设置心跳(setRequestedHeardbeat)为一个合理的值(1个心跳丢失将关闭通道),然后将其传递给ConnectionFactory构造函数。 - Arnon Rotem-Gal-Oz
@Arnon Rotem-Gal-Oz,设置RequestedHeartbeat解决了我的类似问题,该问题表现为独占队列不能及时地在代理中清除。这阻止了使用确定性名称声明独占队列的组件启动。 - drstevens
@drstevens没错- 这基本上是同样的问题。经纪人需要知道客户已经离开以释放资源。 - Arnon Rotem-Gal-Oz

3

回答关闭。这最终不是一个真正的问题。

我是在VirtualBox虚拟机中运行rabbitmq服务器,显然该虚拟机不能正确管理通过NAT的已死入站连接。但是,在物理主机上直接运行mq服务器就可以正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接