JNDI/JMS under HA
JNDI
The only change you have to apply is the JNDI provider URL (SMQP URL). The SMQP-URL has the following format:
smqp://[<user>[:<password>]@](<host>:<port>)|"intravm"[/[host2=<host2>][;port2=<port2>]
[;reconnect=<boolean>][;retrydelay=<long>][;maxretries=<int>][;type=<type>]
[;timeout=<long>][;keepalive=<long>][;debug=<boolean>][;idleclose=<long>]
Where
smqp ::= Specifies the SwiftMQ Protocol
<user> ::= Username. Default is 'anonymous'
<password> ::= User's password. Default is null.
<host> ::= DNS hostname of the 1st HA instance or the keyword "intravm" to connect intra-VM
<port> ::= JMS listener port of the 1st HA instance
host2 ::= DNS hostname of the 2nd HA instance
port2 ::= JMS listener port of the 2nd HA instance
reconnect ::= Specifies whether an automatic reconnect should be done
retrydelay ::= Amount in milliseconds to wait between reconnect retries
maxretries ::= Max. number of reconnect retries
type ::= Class name of the socket factory used by this JMS listener.
In this release, com.swifmq.net.PlainSocketFactory and
com.swiftmq.net.JSSESocketFactory are available. Default is
com.swifmq.net.PlainSocketFactory. See JMS Swiftlet configuration for details.
timeout ::= Specifies a timeout in milliseconds for lookups. If no JNDI object is
received within this time, the lookup throws a NamingException. Default is no timeout;
lookups are waiting until they receive the requested JNDI objects.
keepalive ::= Specifies a keepalive interval in milliseconds. If this value is greater 0, a
timer is created on the client side to send keepalive messages to detect broken
JNDI connections. Default is 60000 (1 minute)
debug ::= If true, debug information are printed to System.out. Good for testing.
idleclose ::= Specifies the maximum idle time of the underlying JMS connection after which it is
closed. It is re-opened when the context is accessed again (i.e. a new lookup).
Default is 60000 ms. To disable it, set it to -1.
Example:
smqp://jms1:4001/host2=jms2;port2=4002;timeout=10000;reconnect=true;retrydelay=1000;maxretries=50
Connects round-robin between host jms1
at port 4001 and jms2
at port 4002 with a delay of 1 second between retries. It stops retries after 50 unsuccessful attempts. JNDI lookup timeout is set to 10 seconds.
JMS
SwiftMQ HA Router provides transparent failover to JMS clients, including recovery of all transactions in transit (incl. XA transactions). Processing continues where it stops before the failover. Persistent messages are never lost or delivered twice. The message sequence is guaranteed.
Non-persistent messages in transit may be lost during failover.
Setting the Delivery Mode / Avoid using Queue Persistency Overwrite Mode
To send persistent messages, you must always use the default delivery mode (persistent according to the JMS specification) or specify it explicitly as a parameter of the send/publish method. This guarantees that the send/publish method is processed synchronously and returns only when the router saved the message to disk. Do not send/publish with a default delivery mode of non-persistent and use the Queue Persistency Overwrite Mode
to set the message as persistent. In that case, the delivery is performed asynchronously and the send/publish method returns before the message has been saved to disk, and can lead to a message loss.
The behavior of 'receive(timeout)' during Failover
A call to receive(timeout)
may time out during failover and return null
if the specified timeout is less than the failover time.
Duplicate Message Detection and JMS Message Id
Duplicate message detection uses the JMS Message-Id. Since it is allowed in JMS to disable the JMS Message-Id, it must be enabled (which is the default) when using HA. Otherwise, duplicate message detection will not work.
Request/Reply with temporary Destinations
Temporary destinations (temp. queues, temp. topics) are reconstructed during failover. They are still valid but now bound to different physical temp. queues at the new HA instance. Since non-persistent messages are lost, a consumer may not receive the expected reply. Further, the consumer of this destination must inform the producer about the new temp. queue or topic after a failover, e.g. by sending the same temporary queue or topic object as JMSReplyTo
for the next request.
To avoid that, regular queues (PtP) or durable subscribers (Pub/Sub) with persistent messages can be used for request/reply.
Failover Configuration
The failover configuration is specified in the connection factory. It contains additional attributes for the 2nd HA instance as well as attributes for reconnecting and retry.
Using a Reconnect Listener
To receive a reconnect event after a failover, a JMS client can register a reconnect listener at a SwiftMQ connection. The interface is:
package com.swiftmq.jms;
public interface ReconnectListener
{
public void reconnected(String host, int port);
}
host
and port
are the host and port of the new HA instance after the failover.
Example to register a reconnect listener:
javax.jms.Connection connection = ...
((com.swiftmq.jms.SwiftMQConnection) connection).addReconnectListener(new ReconnectListener()
{
public void reconnected(String host, int port)
{
// Do stuff
}
});
Reconnect Debug Output
To see debug output during connect and reconnect, set system property
-Dswiftmq.reconnect.debug=true
at your client's JVM command line. Debug output goes to System.out
.