ActiveMQ的断线重连机制

断线重连机制是ActiveMQ的高可用性具体体现之一。

具体就是使用failover方式,使得连接断开之后,可以不断的重试连接到一个或多个brokerURL。

例如:failover:(tcp://127.0.0.1:61616) ,这里可以使用多个url。

默认情况下,如果client与broker直接的connection断开,则client会新起一个线程,

不断的从url参数中获取一个url来重试连接。

这个机制对于在容器中使用的connection木有问题。

activemq-core源码的test中也有多个client与broker之间断开重连10次的例子:

http://svn.apache.org/repos/asf/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/transport/failover/ReconnectTest.java

 

但是对于简单实现的一个独立运行client,一般重连一次就会出现进程退出的bug:https://issues.apache.org/jira/browse/AMQ-796

可以测试如下:

1、通过命令行启动一个broker

2、在java中创建一个connection,添加一个TransportListener,使用如下代码来根据连接断开与重连。

@Override
public void transportInterupted() {
System.out.println(“===>> 断开”);
}
@Override
public void transportResumed() {
System.out.println(“===>> 重连”);
}

3、运行程序

4、停止broker,再启动broker

5、观察到断开与重连

6、再停止broker,发现程序自动退出。

 

程序退出不再重连的原因在于重连的线程是daemon的,连接出错以后,其他线程都退出了,这个线程也随即被销毁掉了。

官方修复过一次,在ActiveMQ Connection Executor上设置了daemon=false,但是这个线程不一定被创建出来。所以bug依然在。

修复的方法很简单:

FailoverTransport.java 的132 行
reconnectTaskFactory = new TaskRunnerFactory();
reconnectTaskFactory.setDaemon(false); // to set daemon=false by kimmking
reconnectTaskFactory.init();

把重连的线程设置成daemon=false就成。

 

然后再按照上面的步骤来执行,发现多次重启broker,都是可以自动重连的。

标签