RabbitMQ:连接恢复机制

问题描述 投票:5回答:2

我使用的是兔mq 3.4.1 java客户端库而无法让自动恢复机制工作。

这就是我创建rabbit mq连接工厂的方法:

factory = new ConnectionFactory();
factory.setUsername(userName);
factory.setPassword(password);
factory.setVirtualHost(virtualHost);
factory.setAutomaticRecoveryEnabled(true);
factory.setNetworkRecoveryInterval(5);
factory.setRequestedHeartbeat(3);

发布消息后,如果我关闭了Rabbit mq代理并再次启动它,我希望恢复机制能够启动并将连接恢复到“理智”状态。但我得到以下错误:

com.rabbitmq.client.AlreadyClosedException: connection is already closed due to connection error; protocol method: #method<connection.close>(reply-code=320, reply-text=CONNECTION_FORCED - broker forced connection closure with reason 'shutdown', class-id=0, method-id=0)
    at com.rabbitmq.client.impl.AMQChannel.ensureIsOpen(AMQChannel.java:190) ~[amqp-client-3.4.1.jar:na]
    at com.rabbitmq.client.impl.AMQChannel.transmit(AMQChannel.java:291) ~[amqp-client-3.4.1.jar:na]
    at com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:654) ~[amqp-client-3.4.1.jar:na]
    at com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:631) ~[amqp-client-3.4.1.jar:na]
    at com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:622) ~[amqp-client-3.4.1.jar:na]

我在这里错过了什么吗?解决此问题的唯一方法是注册ShutDownListener并重新初始化rabbit mq连接工厂,连接和通道。

也回答

“Chrislott”

评论,我看到自动恢复开始恢复。我使用临时频道创建交换:

Channel channel = connection.createChannel();
channel.exchangeDeclare(exchangeName, exchangeType, durable);
channel.close();

当我尝试恢复拓扑时,我看到以下异常:

Caught an exception when recovering topology Caught an exception while recovering exchange testSuccessfulInitVirtualHost_Exchange: channel is already closed due to clean channel shutdown; protocol method: #method<channel.close>(reply-code=200, reply-text=OK, class-id=0, method-id=0)
com.rabbitmq.client.TopologyRecoveryException: Caught an exception while recovering exchange testSuccessfulInitVirtualHost_Exchange: channel is already closed due to clean channel shutdown; protocol method: #method<channel.close>(reply-code=200, reply-text=OK, class-id=0, method-id=0)
    at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.recoverExchanges(AutorecoveringConnection.java:482)
    at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.recoverEntities(AutorecoveringConnection.java:467)
    at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.beginAutomaticRecovery(AutorecoveringConnection.java:411)
    at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.access$000(AutorecoveringConnection.java:52)
    at com.rabbitmq.client.impl.recovery.AutorecoveringConnection$1.shutdownCompleted(AutorecoveringConnection.java:351)
    at com.rabbitmq.client.impl.ShutdownNotifierComponent.notifyListeners(ShutdownNotifierComponent.java:75)
    at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:574)

如果我不关闭用于创建交换的通道,则不会出现上述异常。

java rabbitmq
2个回答
2
投票

我读取RabbitMQ ConnectionFactory#setAutomaticRecoveryEnabled(布尔)方法的主要原因是它能够从NETWORK故障中恢复。

这是一个很好的讨论:https://www.rabbitmq.com/api-guide.html

例如,如果您的机器在一段时间内丢失了通往代理的路由,可能是由于交换机或其他故障,那么自动恢复可以重新建立连接等。文档没有说明有关幸存的代理关闭的信息/ restart,我认为你的期望不合理。

恕我直言从代理重启恢复,关机监听方法似乎是一个坚实的方法。


1
投票

通常兔子客户端应该自己处理恢复 - 你不应该手动重新实现它。至少尝试使用lyra

我在故障转移测试期间遇到了一些问题。连接往往在代理重启时开始永远挂起,因此关闭信号异常是日志中的最后一件事。我通过设置修复它:

factory.setConnectionTimeout(20000);

临时队列也无法恢复恢复。如果你有那些你可能需要做一些额外的处理(再次尝试lyra)。

© www.soinside.com 2019 - 2024. All rights reserved.