This example demonstrates two servers coupled as a live-backup pair for high availability (HA), and a client connection failing over from live to backup when the live server is crashed.
Failover behavior differs whether the JMS session is transacted or not.
When a non-transacted JMS session is used, once and only once delivery is not guaranteed and it is possible some messages will be lost or delivered twice, depending when the failover to the backup server occurs.
It is up to the client to deal with such cases. To ensure once and only once delivery, the client must use transacted JMS sessions (as shown in the example for failover with transactions).
For more information on ActiveMQ failover and HA, and clustering in general, please see the clustering section of the user manual.
To run the example, simply type mvn verify
from this directory
In this example, the live server is server 1, and the backup server is server 0
The connection will initially be created to server1, server 1 will crash, and the client will carry on seamlessly on server 0, the backup server.
initialContext = getContext(1);
Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue"); ConnectionFactory connectionFactory = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");
connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
connection.start();
MessageProducer producer = session.createProducer(queue); MessageConsumer consumer = session.createConsumer(queue);
for (int i = 0; i < numMessages; i++) { TextMessage message = session.createTextMessage("This is text message " + i); producer.send(message); System.out.println("Sent message: " + message.getText()); }
TextMessage message0 = null; for (int i = 0; i < numMessages / 2; i++) { message0 = (TextMessage)consumer.receive(5000); System.out.println("Got message: " + message0.getText()); } message0.acknowledge();
for (int i = numMessages / 2; i < numMessages; i++) { message0 = (TextMessage)consumer.receive(5000); System.out.println("Got message: " + message0.getText()); }
killServer(1); Thread.sleep(2000);
try { message0.acknowledge(); } catch (JMSException e) { System.err.println("Got exception while acknowledging message: " + e.getMessage()); }
for (int i = numMessages / 2; i < numMessages; i++) { message0 = (TextMessage)consumer.receive(5000); System.out.printf("Got message: %s (redelivered?: %s)\n", message0.getText(), message0.getJMSRedelivered()); } message0.acknowledge();
finally
block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objectsfinally { if (connection != null) { connection.close(); } if (initialContext != null) { initialContext.close(); } }