我试图在连接断开的情况下使用自动恢复功能。 我有两个问题:
1)自动恢复代码似乎完全忽略了networkRecoveryInterval。在我的日志文件中,连接断开的1分钟,文件增长到1.5 GB。以下错误不断重复。
在连接恢复期间发现异常! java.net.SocketException:网络无法访问 java.net.PlainSocketImpl.socketConnect(Native Method)at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339) 在 java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) 在 java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182) 在java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391)at java.net.Socket.connect(Socket.java:579)at com.rabbitmq.client.impl.FrameHandlerFactory.create(FrameHandlerFactory.java:32) 在 com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory.newConnection(RecoveryAwareAMQConnectionFactory.java:34) 在 com.rabbitmq.client.impl.recovery.AutorecoveringConnection.recoverConnection(AutorecoveringConnection.java:388) 在 com.rabbitmq.client.impl.recovery.AutorecoveringConnection.beginAutomaticRecovery(AutorecoveringConnection.java:360) 在 com.rabbitmq.client.impl.recovery.AutorecoveringConnection.access $ 000(AutorecoveringConnection.java:48) 在 com.rabbitmq.client.impl.recovery.AutorecoveringConnection $ 1.shutdownCompleted(AutorecoveringConnection.java:345) 在 com.rabbitmq.client.impl.ShutdownNotifierComponent.notifyListeners(ShutdownNotifierComponent.java:75) 在 com.rabbitmq.client.impl.AMQConnection $ MainLoop.run(AMQConnection.java:572) 在java.lang.Thread.run(Thread.java:722)
2)最后当我打开路由器时,网络恢复不起作用。我在我的日志文件中得到了这个。
恢复拓扑时捕获异常同时捕获异常 恢复队列8923yrbk com.rabbitmq.client.TopologyRecoveryException:捕获异常 同时恢复队列8923yrbk at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.recoverQueues(AutorecoveringConnection.java:459) 在 com.rabbitmq.client.impl.recovery.AutorecoveringConnection.recoverEntities(AutorecoveringConnection.java:424) 在 com.rabbitmq.client.impl.recovery.AutorecoveringConnection.beginAutomaticRecovery(AutorecoveringConnection.java:365) 在 com.rabbitmq.client.impl.recovery.AutorecoveringConnection.access $ 000(AutorecoveringConnection.java:48) 在 com.rabbitmq.client.impl.recovery.AutorecoveringConnection $ 1.shutdownCompleted(AutorecoveringConnection.java:345) 在 com.rabbitmq.client.impl.ShutdownNotifierComponent.notifyListeners(ShutdownNotifierComponent.java:75) 在 com.rabbitmq.client.impl.AMQConnection $ MainLoop.run(AMQConnection.java:572) 在java.lang.Thread.run(Thread.java:722)引起: com.rabbitmq.client.AlreadyClosedException:连接已经存在 由于连接错误而关闭;原因: com.rabbitmq.client.MissedHeartbeatException:缺少心跳 心跳= 45秒 com.rabbitmq.client.impl.AMQChannel.ensureIsOpen(AMQChannel.java:190) 在com.rabbitmq.client.impl.AMQChannel.rpc(AMQChannel.java:223)at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:209) 在 com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:118) 在com.rabbitmq.client.impl.ChannelN.queueDeclare(ChannelN.java:779) 在 com.rabbitmq.client.impl.recovery.AutorecoveringChannel.queueDeclare(AutorecoveringChannel.java:230) 在 com.rabbitmq.client.impl.recovery.RecordedQueue.recover(RecordedQueue.java:36) 在 com.rabbitmq.client.impl.recovery.AutorecoveringConnection.recoverQueues(AutorecoveringConnection.java:448) ......还有7个
这是我非常简单的消费者代码。请注意,我在新线程中编写了所有代码,因为我不希望我的构造函数被阻塞。
private ConnectionFactory factory = null;
private Connection connection = null;
private Channel channel = null;
private PaymentInfoFromGlobalServerConsumer() {
new Thread(new Runnable() {
public void run() {
factory = new ConnectionFactory();
try {
factory.setUri(amqpServerUrl);
factory.setAutomaticRecoveryEnabled(true);
factory.setNetworkRecoveryInterval(30000); // In case of broken connection, try again every 30 seconds (hope this is correct understanding)
factory.setRequestedHeartbeat(45); //Keep sending the heartbeat every 45 seconds to prevent any routers from considering the connection stale.
} catch (KeyManagementException | NoSuchAlgorithmException | URISyntaxException e) {
//Will never happen if configured properly
logger.error(e);
return;
}
try {
connection = factory.newConnection();
channel = connection.createChannel();
//Create a durable queue (if not already present)
channel.queueDeclare(merchantId, true, false, false, null);
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(merchantId, false, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String billId = new String(delivery.getBody());
//TODO - Redeliveries are possible as per design
System.out.println(" [x] Received '" + billId + "'");
System.out.println(" [x] Done" );
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
} catch (IOException | ConsumerCancelledException | InterruptedException e) {
e.printStackTrace();
logger.error(e);
} catch (ShutdownSignalException e) {
System.out.println(e.isInitiatedByApplication() + " " + e.isHardError());
} finally {
close();
}
}
}).start();
}
public void close() {
try {
if (channel != null) channel.close();
} catch (IOException | AlreadyClosedException e) {
//Cannot do anything now
}
try {
if (connection != null) connection.close();
} catch (IOException | AlreadyClosedException e) {
//Cannot do anything now
}
}
我是amqp的新手,所以任何帮助都表示赞赏。谢谢
答案 0 :(得分:-1)
尝试恢复拓扑以及连接。
factory.setTopologyRecoveryEnabled(true);