2015-04-21 84 views
5

我使用的是兔子mq 3.4.1的java客戶端庫,並且無法獲得自動恢復機制的工作。RabbitMQ:連接恢復機制

這是我正在創建兔子MQ連接工廠:

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

的消息發佈後,如果我關機兔子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) 

上述異常沒有看到,如果我不關閉用於創建交換的通道。

回答

2

我對RabbitMQ的介紹ConnectionFactory#setAutomaticRecoveryEnabled(Boolean)方法是它主要支持從NETWORK故障中恢復。

這裏有一個很好的討論:https://www.rabbitmq.com/api-guide.html

例如,如果你的機器失去與代理的路線一段時間,可能是由於交換機或其他故障,則自動恢復可以重新建立連接等。該文檔沒有說生存的經紀人關機/重新啓動,我不認爲你的期望是合理的。

恕我直言,從代理重啓恢復,關閉監聽器方法似乎是一個堅實的方法。

+0

但我看到自動恢復踢入恢復。我使用臨時通道創建交換: Channel channel = connection.createChannel(); channel.exchangeDeclare(exchangeName,exchangeType,durable); channel.close(); – user170008

1

通常兔子客戶端應該處理恢復本身 - 你不應該手動重新實現。至少嘗試使用lyra

我在故障轉移測試期間遇到了一些問題。連接往往會在代理重啓時永久掛起,所以關機信號異常是日誌中的最後一件事。我通過設置來修復它:

factory.setConnectionTimeout(20_000); 

恢復與臨時隊列無法良好配合。如果你有那些你可能需要做一些額外的處理(再次,嘗試首先lyra)。