Apache ActiveMQ 集群配置详解

构建高可用的ActiveMQ系统在生产环境中非常重要。对于apache的这个消息中间件实现高可用也非常简单,只要在Apache ActiveMQ单点基本配置基础上做一次配置变更(如果在一台设备上部署多个ActiveMQ,需要修改对应端口号),即可实现。

官方资料:http://activemq.apache.org/clustering.html

ActiveMQ 具有强大和灵活的集群功能,但在使用的过程中会发现很多的缺点, ActiveMQ 的集群方式主要由两种: Master-Slave Broker Cluster

1、Master-Slave

        Master-Slave方式中,只能是Master提供服务,Slave是实时地备份Master的数据,以保证消息的可靠性。当Master失效时,Slave会自动升级为Master,客户端会自动连接到Slave上工作。Master-Slave模式分为三类:Pure Master SlaveShared File System Master SlaveJDBC Master Slave


(1)Pure Master Slave
    官方地址http://activemq.apache.org/pure-master-slave.html

    需要两个Broker,一个作为Master,另一个作为Slave,运行时,Slave通过网络实时从Master处复制数据,同时,如果SlaveMaster失去连接,Slave就会自动升级为Master,继续为客户端提供消息服务,如图所示:

    实践时,我们使用两个ActiveMQ服务器,一个作为MasterMaster不需要做特殊的配置;另一个作为Slave,配置${ACTIVEMQ_HOME}/conf/activemq.xml文件,在节点中添加连接到MasterURI和设置Master失效后不关闭Slave,如下:

Xml代码   收藏代码
  1. <broker xmlns="http://activemq.apache.org/schema/core" brokerName="pure_slave" masterConnectorURI="tcp://0.0.0.0:61616" shutdownOnMasterFailure="false" dataDirectory="${activemq.base}">  

 

 同时修改Slave的服务端口,如:

 

Xml代码   收藏代码
  1. <transportConnectors>  
  2.             <transportConnector name="openwire" uri="tcp://0.0.0.0:61617"/>  
  3. transportConnectors>  

 

为了看到实践的效果,MasterSlave的消息持久化介质都是采用MySQL,并且MasterSlave分别连接不同的数据库。

    在消息生产者应用和消息消费者应用的Spring配置文件中添加以下红色内容:

 

Xml代码   收藏代码
  1. <property name="brokerURL" value="failover:(tcp://localhost:61616,tcp://localhost:61617)?initialReconnectDelay=100" />  

     配置完成后,我们可以通过以下步骤来进行测试:

A、启动MasterSlave,启动消息生产者应用,并分别发送一些Queue消息和Topic消息,如果此时订阅Topic消息的消费者设置了clientID,我们就可以在Master的数据库和Slave的数据库中看到尚未消费的消息,包括QueueTopic的消息;

B、启动消费者应用,可以接收到消息;

C、关闭消费者,生产者继续发送一些消息A

D、停止Master

E、生产者继续发送消息B

F、启动消费者应用,消费者可以接收到消息A和消息B,说明Slave接替了Master的工作并复制了Master的消息。

    这种方式只能两台机器做集群,可以起到很好的双机热备功能,但只能失效一次,只能通过停机恢复Master-Slave结构。该模式实际应用场景并不广泛。


(2)Shared File System Master Slave
   官方地址http://activemq.apache.org/masterslave.html

        Shared File System Master Slave就是利用共享文件系统做ActiveMQ集群,是基于ActiveMQ的默认数据库kahaDB完成的,kahaDB的底层是文件系统。这种方式的集群,Slave的个数没有限制,哪个ActiveMQ实例先获取共享文件的锁,那个实例就是Master,其它的ActiveMQ实例就是Slave,当当前的Master失效,其它的Slave就会去竞争共享文件锁,谁竞争到了谁就是Master。这种模式的好处就是当Master失效时不用手动去配置,只要有足够多的SlaveShared File System Master Slave模式如图所示:

    本例子是在一台机器上运行三个ActiveMQ实例,需要对ActiveMQ的配置文件做一些简单的配置,就是把持久化适配器的存储目录改为本地磁盘的一个固定目录,三个实例共享这个目录,如下:

 

Xml代码   收藏代码
  1. <span style="color: #ff0000;"><persistenceAdapter>  
  2.     <kahaDB directory="E:/XXX/XXX/XXX/cluster/shared_file/data/kahadb" />  
  3. persistenceAdapter>span>  

然后修改ActiveMQ实例的服务端口和jetty的服务端口,防止端口占用异常。启动三个ActiveMQ实例,就可以进行测试了。



“Apache ActiveMQ单点基本配置” 原配置内容:

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. <persistenceAdapter>    
  2.             <kahaDB directory="${activemq.data}/kahadb"    
  3.                     enableIndexWriteAsync="true"    
  4.                     enableJournalDiskSyncs="false"/>    
  5.             <!-- --&gt    
  6.         persistenceAdapter>   
修改为:
[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. <persistenceAdapter>  
  2.              <kahaDB directory="X:\\shareBrokerData"  
  3.                         enableIndexWriteAsync="true"  
  4.                         enableJournalDiskSyncs="false"/>  
  5.         persistenceAdapter>  
注意

1、前面提到部署一台设备上的ActiveMQ系统,需要修改对应的端口号,如ActiveMQ对外的监听端口61616和jetty的监听端口8161等。

2、如果多套ActiveMQ部署在不同的设备上,这里的directory应该指向一个远程的系统目录(分布式文件系统)


Producer for java:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. ActiveMQConnectionFactory connectionFactory =     
  2.         new ActiveMQConnectionFactory("failover:(  
  3. tcp://192.168.0.87:61616?wireFormat.maxInactivityDuration=0,  
  4. tcp://192.168.0.87:61617?wireFormat.maxInactivityDuration=0)");    
  5.     Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);    
  6.         
  7.     Queue queue = session.createQueue(qName);    
  8.     ActiveMQMessageProducer producer = (ActiveMQMessageProducer) session.createProducer(queue); // Default DeliveryMode.PERSISTENT    
  9.     //producer.setPriority(3); // Default priority 4.    
  10.     //producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);    
  11.         
  12.     session.createObjectMessage();    
  13.     jmsMessage.setObject(message);    
  14.     while(true){          
  15.   
  16.          producer.send(jmsMessage);    
  17.          TimeUnit.MILLISECONDS.sleep(10);  
  18.   
  19.  }  

Consumer for java:


[java]
  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. final String qName = "Test.foo?consumer.prefetchSize=100";  
  2. ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("  
  3. failover:(  
  4. tcp://192.168.0.87:61616,  
  5. tcp://192.168.0.87:61617  
  6. )");   
  7. Connection connection = connectionFactory.createConnection();  
  8. connection.start();  
  9.   
  10. final Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);   
  11. Destination destination = session.createQueue(qName);  
  12. ActiveMQMessageConsumer consumer = (ActiveMQMessageConsumer) session.createConsumer(destination);  
  13. System.out.println(consumer.getPrefetchNumber());  
  14.   
  15. //listener 方式   
  16. consumer.setMessageListener(new MessageListener() {  
  17.      public void onMessage(Message msg) {  
  18.      //TODO something....   
  19.         try {  
  20.             System.out.println("收到消息:"+counter.incrementAndGet()+","+msg);  
  21.         } catch (JMSException e1) {  
  22.         // TODO Auto-generated  
  23.          catch blocke1.printStackTrace();  
  24.         }  
  25.      }  
  26.  });  

通过failover方式进行连接,多个ActiveMQ 实例地址使用英文逗号隔开,当某个实例断开时会自动重连,但如果所有实例都失效,failover默认情况下会无限期的等待下去,不会有任何提示。



failover参数配置参考:

http://activemq.apache.org/failover-transport-reference.html



(3)JDBC Master Slave
   官方地址http://activemq.apache.org/masterslave.html

        JDBC Master Slave模式和Shared File Sysytem Master Slave模式的原理是一样的,只是把共享文件系统换成了共享数据库。我们只需在所有的ActiveMQ的主配置文件中(${ACTIVEMQ_HOME}/conf/activemq.xml)添加数据源,所有的数据源都指向同一个数据库,如:

 

Xml代码   收藏代码
  1. <bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
  2.         <property name="driverClassName" value="com.mysql.jdbc.Driver"/>  
  3.         <property name="url" value="jdbc:mysql://localhost:3306/cluster_jdbc?relaxAutoCommit=true"/>  
  4.         <property name="username" value="root"/>  
  5.         <property name="password" value="root"/>  
  6.         <property name="maxActive" value="200"/>  
  7.         <property name="poolPreparedStatements" value="true"/>  
  8. bean>  

 然后修改持久化适配器。这种方式的集群相对Shared File System Master Slave更加简单,更加容易地进行分布式部署,但是如果数据库失效,那么所有的ActiveMQ实例都将失效,它的性能受限于数据库。

 

以上三种方式的集群都不支持负载均衡,但可以解决单点故障的问题,以保证消息服务的可靠性。

2、Broker Cluster

        Broker Cluster主要是通过network of Brokers在多个ActiveMQ实例之间进行消息的路由。Broker的集群分为Static DiscoveryDynamic Discovery两种。

(1)Static Discovery集群
   官方地址http://activemq.apache.org/static-transport-reference.html

Static Discovery集群就是通过硬编码的方式使用所有已知ActiveMQ实例节点的URI地址。如:消息生产者应用连接一个ActiveMQ实例,我们暂时称为MQ1,所有的消息都由该实例提供;两个消息消费者应用分别连接另外两个ActiveMQ实例,分别为MQ2MQ3,两个消息消费者需要消费MQ1上的消息,但它们连接的都不是MQ1,可以通过Static Discovery方式把MQ1上的消息路由到MQ2MQ3,为了保证消费者不因某个节点的失效而导致不能消费消息,在消费者应用中需要配置所有节点的URI

 

    生产者ActiveMQ实例不需要特殊的配置,所有的消费者ActiveMQ实例需要添加networkConnectors节点,连接到生产者MQ实例,如:

 

Xml代码   收藏代码
  1. <span style="color: #ff0000;"><networkConnectors>  
  2. <networkConnector uri="static:failover://(tcp://localhost:61616)" duplex="true" />  
  3. networkConnectors>span>  

 

上面这段配置需要加在节点的前面。然后在消费者应用中设置brokerURL的值如:

 

Xml代码   收藏代码
  1. <property name="brokerURL" value="<span style="color: #ff0000;">failover:(tcp://localhost:61617)span>?initialReconnectDelay=100/>  

         Static Discovery集群方式有些缺点,如不能解决单点故障问题,若某个 Broker失效时,有可能造成数据的丢失,动态添加节点不够智能化。

  

    更加详细的说明与配置请参考:http://activemq.apache.org/networks-of-brokers.html

(2)Dynamic Discovery集群
   官方地址http://activemq.apache.org/static-transport-reference.html

        Dynamic Discovery集群方式在配置ActiveMQ实例时,不需要知道所有其它实例的URI地址,只需在所有实例的${ACTIVEMQ_HOME}/conf/activemq.xml文件中添加以下内容:

 

Xml代码   收藏代码
  1. <span style="color: #ff0000;"><networkConnectors>  
  2. <networkConnector uri="multicast://default" />  
  3. networkConnectors>span>  

 

 同时在节点中添加以下红色部分内容:

 

Xml代码   收藏代码
  1. <transportConnectors>  
  2. <transportConnector name="openwire" uri="tcp://0.0.0.0:61616" <span style="color: #ff0000;">discoveryUri="multicast://default"span> />  
  3. transportConnectors>  

 

这样就可以实现消息在所有ActiveMQ实例之间进行路由。Dynamic Discovery集群方式的缺点和Static Discovery一样。

    从以上的分析可以看出,Master-Slave模式不支持负载均衡,但可以通过消息的实时备份或共享保证消息服务的可靠性,Broker Cluster模式支持负载均衡,可以提高消息的消费能力,但不能保证消息的可靠性。所以为了支持负载均衡,同时又保证消息的可靠性,我们可以采用Msater-Slave+Broker Cluster的模式。



来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9399028/viewspace-1650271/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/9399028/viewspace-1650271/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值