本文章参考了:http://blog.csdn.net/jason5186/article/details/18702523
一、为什么要配置集群
构建高可用的AMQ系统在生产环境中是非常重要的,对于这个apache的消息中间件实现高可用非常简单,只要在Apache ActiveMQ单点基本配置基础上做一次配置变更(如果在一台设备上部署多个AMQ,需要修改对应端口号),即可实现。
二、集群配置方案分析
AMQ实现高可用部署有三种方案:
1、Master-Slave
2、SharedFile System Master Slave
3、JDBCMaster Slave
第一种方案由于只可以由两个AMQ实例组件,实际应用场景并不广泛;
而第三种方案支持N个AMQ实例组网,但他的性能会受限于数据库;
而第二种方案同样支持N个AMQ实例组网,但由于他是基于kahadb存储策略,亦可以部署在分布式文件系统上,应用灵活、高效且安全。
三、配置文件改写
“Apache ActiveMQ单点基本配置” 原配置内容:
[html] view plain copy print?
- <persistenceAdapter>
- <kahaDB directory="${activemq.data}/kahadb"
- enableIndexWriteAsync="true"
- enableJournalDiskSyncs="false"/>
- <!--<amqPersistenceAdapter directory="${activemq.data}/activemq-data" /> -->
- </persistenceAdapter>
修改为:
[html] view plain copy print?
- <persistenceAdapter>
- <kahaDB directory="X:\\shareBrokerData"
- enableIndexWriteAsync="true"
- enableJournalDiskSyncs="false"/>
- </persistenceAdapter>
注意:
1、前面提到部署一台设备上的AMQ系统,需要修改对应的端口号,如AMQ对外的监听端口61616和jetty的监听端口8161等。
我这里 activemq用的端口是61616, activemq1用的端口是61617
2、如果多套AMQ部署在不同的设备上,这里的directory应该指向一个远程的系统目录(分布式文件系统)
四、测试例子
1、producer for C++
int main(int argc , char* argv[])
{
activemq::library::ActiveMQCPP::initializeLibrary();
std::cout << "Starting produce message:" << std::endl;
std::string brokerURI ="failover://(tcp://192.168.9.131:61616,tcp://192.168.9.131:61617)?initialReconnectDelay=1000";
unsigned int numMessages = 20;
std::string destURI = "test.chen";
bool useTopics = false;
SimpleProducer producer( brokerURI, numMessages, destURI, useTopics );
producer.run();
producer.close();
activemq::library::ActiveMQCPP::shutdownLibrary();
}
2、consumer for c++
nt main(int argc, char* argv[])
{
activemq::library::ActiveMQCPP::initializeLibrary();
std::string brokerURI = "failover://(tcp://192.168.9.131:61616,tcp://192.168.9.131:61617)?initialReconnectDelay=1000";
std::string destURI = "test.chen";
bool useTopics = false;
bool clientAck = false;
SimpleAsyncConsumer consumer( brokerURI, destURI, useTopics, clientAck );
consumer.runConsumer();
std::cout << "Press 'q' to quit" << std::endl;
while( std::cin.get() != 'q') {}
consumer.close();
activemq::library::ActiveMQCPP::shutdownLibrary();
}
通过failover方式进行连接,多个AMQ实例地址使用英文逗号隔开,当某个实例断开时会自动重连,但如果所有实例都失效,failover默认情况下会无限期的等待下去,不会有任何提示。
failover参数配置参考:
http://activemq.apache.org/failover-transport-reference.html
五、测试结果
1、开启所有的mq(这里在同台机器上配置了2个mq程序)
./activemq start
/activemq1 start
2、启动revicer,查看连接的mq
[wdm@localhost ~]$ netstat -lantp | egrep "61616|61617|8161"
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:8161 0.0.0.0:* LISTEN 8784/java
tcp 0 0 0.0.0.0:61616 0.0.0.0:* LISTEN 8784/java
tcp 0 0 192.168.9.131:32940 192.168.9.131:61616 ESTABLISHED 8870/./receive1
tcp 0 0 192.168.9.131:61616 192.168.9.131:32940 ESTABLISHED 8784/java
3、启动sender,发现发送接收数据正常,此时停掉61616的程序,再次查看reciver连接的mq程序
/activemq1 stop
[wdm@localhost ~]$ netstat -lantp | egrep "61616|61617|8161"
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:61617 0.0.0.0:* LISTEN 8820/java
tcp 0 0 192.168.9.131:39485 192.168.9.131:61616 TIME_WAIT -
tcp 0 0 192.168.9.131:61616 192.168.9.131:32940 TIME_WAIT -
tcp 0 0 192.168.9.131:55345 192.168.9.131:61617 ESTABLISHED 8870/./receive1
tcp 0 0 192.168.9.131:61617 192.168.9.131:55345 ESTABLISHED 8820/java
4、再次发送数据,发现还是能接收到、高可用集群配置成功