2015-04-21 13 views
5

Sto usando la libreria client java coniglio 3.4.1 java e non riesco a far funzionare il meccanismo di ripristino automatico.RabbitMQ: meccanismo di ripristino connessione

Questo è come mi sto creando il coniglio produzione connessioni mq:

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

Dopo la pubblicazione di un messaggio, se l'arresto il broker di coniglio mq e portarlo di nuovo, mi aspetto che il meccanismo di recupero a calciare in e avere la connessione ripristinata in uno stato 'sano'. Ma ho il seguente errore:

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] 

Mi manca qualcosa qui? L'unico modo per ovviare a questo problema è registrare un ShutDownListener e reinizializzare la factory, la connessione ei canali della connessione coniglio mq.

anche rispondere

"chrislott"

commento, vedo il ripristino automatico calci per recuperare. Creo uno scambio utilizzando una temporanea di canale:

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

E vedo l'eccezione di seguito quando il suo tentativo di recuperare la topologia:

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) 

È possibile che eccezione non si vede se non chiudo la canale utilizzato per creare lo scambio.

risposta

2

La lettura del metodo RabbitMQ ConnectionFactory # setAutomaticRecoveryEnabled (Boolean) è che abilita principalmente il ripristino dall'errore NETWORK.

Ecco una bella discussione: https://www.rabbitmq.com/api-guide.html

Per esempio, se la macchina perde un percorso al broker per un periodo di tempo, forse a causa di un interruttore o altro guasto, quindi il recupero automatico può ristabilire un connessione ecc. Il documento non dice nulla di arresto/riavvio del broker sopravvissuto, non credo che le tue aspettative siano ragionevoli.

IMHO per ripristinare da un riavvio del broker, l'approccio shutdown-listener sembra essere un approccio solido.

+0

Ma vedo il recupero automatico che si avvia per recuperare. Creo uno scambio utilizzando un canale temporaneo: Canale channel = connection.createChannel(); channel.exchangeDeclare (exchangeName, exchangeType, durable); channel.close(); – user170008

1

Normalmente il client coniglio deve gestire il recupero stesso - non è necessario reimplementare lo stesso manualmente. Almeno prova a usare lyra.

Ho avuto alcuni problemi durante il test di failover. Le connessioni tendono a bloccarsi per sempre sul riavvio del broker, quindi l'eccezione del segnale di spegnimento era l'ultima cosa nei log. L'ho risolto impostando:

factory.setConnectionTimeout(20_000); 

Anche il recupero non ha funzionato bene con le code temporanee. Se ne possiedi probabilmente dovrai fare qualche ulteriore trattamento (di nuovo, prova prima Lyra).