Client failover with static clusters in HA mode
hyrax May 28, 2013 7:27 PMHi,
I'm using HornetQ hornetq-2.3.0.Final now. I was tring to set up live-backup server using static cluster. What I expect to see is that when I shut down the live server, the client should automatically swtich to the backup server. FYI, I am using jms url (like jms://localhost:5445) to connect client with hornetq server. What I have achieved is that from the logs, I can see the backup server got announced and became live when I shutdown the live server but the consumer got disconnected as indicated in the log:
2013-05-28T18:37:22.600 WARNING: Reconnect start failed.
javax.jms.JMSException: Failed to create session factory
at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:605)
at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:119)
at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:114)
at com.xxxxx.jms.JmsMessageCenter.start(JmsMessageCenter.java:120)
at com.xxxxx.MessageCenter.reconnect(MessageCenter.java:106)
at com.xxxxx.jms.JmsMessageCenter.reconnect(JmsMessageCenter.java:159)
at com.xxxxx.jms.JmsMessageCenter$Receiver.run(JmsMessageCenter.java:351)
at java.lang.Thread.run(Thread.java:722)
Caused by: HornetQException[errorCode=2 message=Cannot connect to server(s). Tried with all available servers.]
at org.hornetq.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:774)
at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:601)
... 7 more
The key part of configuration files are listed below:
On the live server side:
hornetq-configuration.xml
<clustered>true</clustered> <failover-on-shutdown>true</failover-on-shutdown> <allow-failback>true</allow-failback> <shared-store>true</shared-store> .... <connectors> <connector name="netty"> <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> <param key="host" value="localhost"/> <param key="port" value="5445"/> </connector> <connector name="netty-backup"> <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> <param key="host" value="localhost"/> <param key="port" value="5446"/> </connector> <connector name="netty-throughput"> <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> <param key="host" value="localhost"/> <param key="port" value="5455"/> <param key="batch-delay" value="50"/> </connector> </connectors> <acceptors> <acceptor name="netty"> <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class> <param key="host" value="localhost"/> <param key="port" value="5445"/> </acceptor> <acceptor name="netty-throughput"> <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class> <param key="host" value="localhost"/> <param key="port" value="5455"/> <param key="batch-delay" value="50"/> <param key="direct-deliver" value="false"/> </acceptor> </acceptors> ... <cluster-connections> <cluster-connection name="my-cluster"> <address>jms</address> <connector-ref>netty</connector-ref> <discovery-group-ref discovery-group-name="dg-group1"/> </cluster-connection> </cluster-connections> ...
hornetq-jms.xml
... <connection-factory name="NettyConnectionFactory"> <xa>false</xa> <connectors> <connector-ref connector-name="netty"/> <connector-ref connector-name="netty-backup"/> </connectors> <entries> <entry name="/ConnectionFactory"/> </entries> <ha>true</ha> <confirmation-window-size>1</confirmation-window-size> <!-- Pause 1 second between connect attempts --> <retry-interval>1000</retry-interval> <!-- Multiply subsequent reconnect pauses by this multiplier. This can be used to implement an exponential back-off. For our purposes we just set to 1.0 so each reconnect pause is the same length --> <retry-interval-multiplier>1.0</retry-interval-multiplier> <!-- Try reconnecting an unlimited number of times (-1 means "unlimited") --> <reconnect-attempts>-1</reconnect-attempts> </connection-factory> ...
On the backup server side:
<clustered>true</clustered> <failover-on-shutdown>true</failover-on-shutdown> <allow-failback>true</allow-failback> <shared-store>true</shared-store> <backup>true</backup> ... <connectors> <connector name="netty"> <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> <param key="host" value="localhost"/> <param key="port" value="5446"/> </connector> <connector name="netty-live"> <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> <param key="host" value="localhost"/> <param key="port" value="5445"/> </connector> <connector name="netty-throughput"> <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> <param key="host" value="localhost"/> <param key="port" value="5455"/> <param key="batch-delay" value="50"/> </connector> </connectors> <acceptors> <acceptor name="netty"> <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class> <param key="host" value="localhost"/> <param key="port" value="5446"/> </acceptor> <acceptor name="netty-throughput"> <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class> <param key="host" value="localhost"/> <param key="port" value="5455"/> <param key="batch-delay" value="50"/> <param key="direct-deliver" value="false"/> </acceptor> </acceptors> ... <cluster-connections> <cluster-connection name="my-cluster"> <address>jms</address> <connector-ref>netty</connector-ref> <retry-interval>500</retry-interval> <use-duplicate-detection>true</use-duplicate-detection> <forward-when-no-consumers>true</forward-when-no-consumers> <max-hops>1</max-hops> <static-connectors> <connector-ref>netty</connector-ref> <connector-ref>netty-live</connector-ref> </static-connectors> </cluster-connection> </cluster-connections> ...
hornetq-jms.xml
... <connection-factory name="NettyConnectionFactory"> <xa>false</xa> <connectors> <connector-ref connector-name="netty"/> <connector-ref connector-name="netty-live"/> </connectors> <entries> <entry name="/ConnectionFactory"/> </entries> <ha>true</ha> <confirmation-window-size>1</confirmation-window-size> <!-- Pause 1 second between connect attempts --> <retry-interval>1000</retry-interval> <!-- Multiply subsequent reconnect pauses by this multiplier. This can be used to implement an exponential back-off. For our purposes we just set to 1.0 so each reconnect pause is the same length --> <retry-interval-multiplier>1.0</retry-interval-multiplier> <!-- Try reconnecting an unlimited number of times (-1 means "unlimited") --> <reconnect-attempts>-1</reconnect-attempts> </connection-factory> ...
My client side code is java based and it supports two ways of connecting to a hornetq server: by jnp and by jms. In my case, the jnp way (url: jnp://localhost:1099 ) would work but the jms way doesn't.
To Create a connection factory with url jms://<host>:<port>, we are using code like:
Map<String, Object> connectionParams = new HashMap<>(); connectionParams.put(TransportConstants.PORT_PROP_NAME, port); connectionParams.put(TransportConstants.HOST_PROP_NAME, host); TransportConfiguration transportConfiguration = new TransportConfiguration(NettyConnectorFactory.class.getName(), connectionParams); return HornetQJMSClient.createConnectionFactoryWithHA(JMSFactoryType.CF, transportConfiguration);
I guess there's something missing in my client side code,but I can't figure out what it would be during a long time of searching. Also, I don't want to do the same as demonstrated in 38.2.2.2.2. Configuring client discovery using JMS because I'm not allowed to pass the port of backup server to the app.
Any thought or idea will be appreciated.
Thanks in advance,
Hyrax