手把手教你如何玩转ActiveMQ集群

267 阅读9分钟
原文链接: www.javazhiyin.com

ActiveMQ的集群

为什么要进行集群呢?

原因一:实现高可用:以排除单点故障所引起的服务终端。

原因二:实现负载均衡:以提升效率为更多的客户进行服务。

集群的方式有哪些?

方式一:客户端集群:多个客户端消费同一个队列。

方式二:Broker clusters:多个Broker之间同步消息。(实现负载均衡)

 网络连接器:用于配置ActiveMQ服务器与服务器之间的网络通讯方式,用于服务器透析消息。主要分为静态连接和动态连接。

方式三:Master Slave :实现高可用。 这种方式的话,可以联想到Mysql的主从配置和Zookeeper的负载均衡的主竞争关系master。

我们在实际的开发中,一般都是将方式二和方式三进行集成,从而实现高可用和负载均衡。下面的话,我也就这样的配置思想来进行讲解:(通过三台服务器来模拟消息集群的实现)

搭建步骤(基于Windows环境,而Linux环境也是一样的操作) 三台服务器的大体功能和描述:

由于自己没有三台服务器,所以就用自己的一台电脑来模拟三台消息服务器,其实这个就是假设有三个不同ActiveMQ消息服务器了。

1. 复制三个ActiveMQ的服务配置到一个公共目录

2. 修改activeMQA的配置文件

 只需要在activemq.xml添加如下内容:

<networkConnectors>
 <networkConnector name="local_network" uri ="static:(tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)" /> 
</networkConnectors>

 

3. 修改ActiveMQB的配置文件

(1)首先在activemq,xml中添加如下内容:

<!--修改服务端口-->
 <transportConnector name="openwire" uri="tcp://0.0.0.0:61617?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> 
<networkConnectors> 
<networkConnector name="networktoA" uri="static:(tcp://127.0.0.1:61616)" /> 
</networkConnectors> 
<!--并修改下面这个标签的内容 , 作为B和C的共享文件,目录就是自己之前创建的一个文件(可以回看上面的整个结构)--> 
<persistenceAdapter> 
<kahaDB directory="D:\Download\MQJiQun\shareDB"/> 
</persistenceAdapter>

 

(2)修改jetty.xml内容,修改服务器的服务端口

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
 <!-- the default port number for the web console --> 
<property name="host" value="0.0.0.0"/>
 <property name="port" value="8162"/> 
</bean>

 

4. 修改ActiveMQC的配置文件(其实类似和B一样,只是服务端口不一样)

(1)修改activemq.xml中的内容 。

<!--修改服务端口-->
 <transportConnector name="openwire" uri="tcp://0.0.0.0:61618?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
 <networkConnectors> 
<networkConnector name="networktoA" uri="static:(tcp://127.0.0.1:61616)" />
 </networkConnectors>
 <!--并修改下面这个标签的内容 , 作为B和C的共享文件,目录就是自己之前创建的一个文件(可以回看上面的整个结构)--> 
<persistenceAdapter> 
<kahaDB directory="D:\Download\MQJiQun\shareDB"/> 
</persistenceAdapter>

 

(2)修改jetty.xml中的内容

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
 <!-- the default port number for the web console --> 
<property name="host" value="0.0.0.0"/> 
<property name="port" value="8163"/>
 </bean>

 

5. 集群搭建完成~~~~

集群测试(基于IDEA编辑器+Maven)

步骤:

(1)创建Maven项目

(2)导入依赖

<!--添加activemq的依赖--> 
<dependency> 
<groupId>org.apache.activemq</groupId> 
<artifactId>activemq-all</artifactId> 
<version>5.9.0</version> 
</dependency>

 

(3)编写生产者代码

package com.hnu.scw.queue;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
/**
 * @ Author     :scw
 * @ Date       :Created in 上午 11:06 2018/7/14 0014
 * @ Description:用于消息的创建类
 * @ Modified By:
 * @Version: $version$
 */
public class MessageProducer {
    //通过集群的方式进行消息服务器的管理(failover就是进行动态转移,当某个服务器宕机,
    // 那么就进行其他的服务器选择,randomize表示随机选择)
    private static final String ACTIVEMQ_URL = "failover:(tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)?randomize=true";
    //定义发送消息的队列名称
    private static final String QUEUE_NAME = "MyMessage";
 
    public static void main(String[] args) throws JMSException {
        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
       //创建连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //打开连接
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建队列目标
        Destination destination = session.createQueue(QUEUE_NAME);
        //创建一个生产者
        javax.jms.MessageProducer producer = session.createProducer(destination);
        //创建模拟100个消息
        for (int i = 1 ; i <= 100 ; i++){
            TextMessage message = session.createTextMessage("当前message是:" + i);
            //发送消息
            producer.send(message);
            //在本地打印消息
            System.out.println("我现在发的消息是:" + message.getText());
        }
        //关闭连接
        connection.close();
    }
 
}

 

(4)编写消费者代码 。

package com.hnu.scw.queue;
 
import org.apache.activemq.ActiveMQConnectionFactory;
 
import javax.jms.*;
 
/**
 * @ Author     :scw
 * @ Date       :Created in 上午 11:30 2018/7/14 0014
 * @ Description:消息消费者
 * @ Modified By:
 * @Version: $version$
 */
public class MessageConsumer {
    //通过集群的方式进行消息服务器的管理(failover就是进行动态转移,当某个服务器宕机,
    // 那么就进行其他的服务器选择,randomize表示随机选择)
    private static final String ACTIVEMQ_URL = "failover:(tcp://127.0.0.1:61616,tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)?randomize=true";
    //定义发送消息的队列名称
    private static final String QUEUE_NAME = "MyMessage";
 
    public static void main(String[] args) throws JMSException {
        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //创建连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //打开连接
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建队列目标
        Destination destination = session.createQueue(QUEUE_NAME);
        //创建消费者
        javax.jms.MessageConsumer consumer = session.createConsumer(destination);
        //创建消费的监听
        consumer.setMessageListener(new MessageListener() {
            @Override
            public void onMessage(Message message) {
                TextMessage textMessage = (TextMessage) message;
                try {
                    System.out.println("获取消息:" + textMessage.getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });
    }
 
}

 

(5)进行查看各自的服务器的消息队列的情况。

1. 首先,是要确保三个ActiveMQ服务器都进行打开。分析:当三个都服务都运行之后,我们从浏览器运行各自的地址,会发现: 比如:我这里的三个服务的地址分别如下:

– http://127.0.0.1:8161/

– http://127.0.0.1:8162/

– http://127.0.0.1:8163/

重点 为什么前面两个都可以访问,而第三个不可以呢?(同样也是按照我的这样的服务器打开方式哦。先打开的服务器A,接着B,最后C)但是,运行的时候,提示都成功了呀。。为什么为什么???

分析:

其实很简单,我说过B和C是一种master/slave的方式,当B运行之后就获得了master的权限,那么C服务是可以看到是一种监听的状态,只有当B宕机之后,才有可能获取master的资源权限,所以,这时候C的地址当然就无法访问啦。这就是负载均衡的一种主/从服务的结构。当然,你可以试着先打开C,再打开B,这时候效果就反过来了。欢迎尝试哦~~~ 

2. 再运行MessageProducer的类,用于产生消息。这时候,大家可以去查看每个服务器的地址,来观察消息的产生情况。我的消息是产生在服务器B的里面啦(通过访问各个服务器的地址URL)。。。。。。

3. 再运行MessageConsumer的类,用于消费消息。这时候,同样可以去查看每个服务器的地址中的消息队列的情况,来观察消息的消费情况。

 4. 如果,我们在生产者产生了消息之后,服务器B突然宕机了怎么办怎么办??

分析:

其实,这时候服务器C就一样有消息保存进行同步了。。是不是这样就是一种高可用的架构了呢????大家,可以试试哦。。把B服务器关掉,再去访问服务器C的地址,就发现如下的结果。

这时候服务器C就作为了master,所以,类似zookeeper就是这样的一种方式的哦。~

总结

好了,对于集群方面的简单使用就到这里了。其实已经可以根据这个进行扩展了,所以,小伙伴要好好理解这里面的过程和作用,这样才能够学以致用。。。

具体的话,大家可以通过这个链接进行访问原文(格式更加友好一些啦,并且包含了ActiveMQ的入门知识):

blog.csdn.net/cs_hnu_scw/…

感谢各位的阅读浏览~~~共同学习,进步~~~

更多同类文章推荐:

  1. SpringBoot整合MyBatis
  2. Mybatis学习系列(一)入门简介
  3. 使用SpringBoot搭建应用开发框架(5)数据库乐观锁
  4. 使用SpringBoot搭建应用开发框架(7)Redis缓存
  5. apache和tomcat区别
  6. 使用SpringBoot搭建应用开发框架(2)基础结构功能
  7. 23种设计模式- 组合模式
  8. 23种设计模式-备忘录模式