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

AMQ实现高可用部署有三种方案: 
1、Master-Slave 
2、SharedFile System Master Slave 
3、JDBCMaster Slave

第一种方案由于只可以由两个AMQ实例组件,实际应用场景并不广泛; 
第三种方案支持N个AMQ实例组网,但他的性能会受限于数据库; 
第二种方案同样支持N个AMQ实例组网,但由于他是基于kahadb存储策略,亦可以部署在分布式文件系统上,应用灵活、高效且安全。

shared filesystem Master-Slave部署方式主要是通过共享存储目录来实现master和slave的热备,所有的ActiveMQ应用都在不断地获取共享目录的控制权,哪个应用抢到了控制权,它就成为master。

多个共享存储目录的应用,谁先启动,谁就可以最早取得共享目录的控制权成为master,其他的应用就只能作为slave。

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

<persistenceAdapter> 
            <kahaDB directory="${activemq.data}/kahadb"/> 
</persistenceAdapter>

修改为:

<persistenceAdapter> 
             <kahaDB directory="D:\\ActiveMQ Cluster\\shareBrokerData" enableIndexWriteAsync="true"  enableJournalDiskSyncs="false"/> 
</persistenceAdapter>

在D:\\ActiveMQ Cluster目录先创建shareBrokerData文件夹。

注意:

1.前面提到如果在一台设备上部署多个AMQ,需要修改对应端口号,如AMQ对外的监听端口61616和jetty的监听端口8161等。 
2.如果多套AMQ部署在不同的设备上,这里的directory应该指向一个远程的系统目录(分布式文件系统) 
3.客户端通过failover方式进行连接,多个AMQ实例地址使用英文逗号隔开,当某个实例断开时会自动重连,但如果所有实例都失效,failover默认情况下会无限期的等待下去,不会有任何提示。

下面为在一台设备上部署两个AMQ示例: 
ActiveMQ A 
1.activemq.xml修改监听端口:

<transportConnectors> 
            <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> 
<!-- add &amp;wireFormat.maxInactivityDuration=0 --> 
            <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireformat.maxFrameSize=104857600&amp;wireFormat.maxInactivityDuration=0" discoveryUri="multicast://default"/> 
            <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireformat.maxFrameSize=104857600&amp;wireFormat.maxInactivityDuration=0"/>

</transportConnectors>

2.jetty.xml修改监听端口:

<property name="connectors"> 
            <list> 
                <bean id="Connector" class="org.eclipse.jetty.server.nio.SelectChannelConnector"> 
                    <property name="port" value="8166" /> 
                </bean> 
                <!-- 
                    Enable this connector if you wish to use https with web console 
                --> 
                <!-- 
                <bean id="SecureConnector" class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector"> 
                    <property name="port" value="8162" /> 
                    <property name="keystore" value="file:${activemq.conf}/broker.ks" /> 
                    <property name="password" value="password" /> 
                </bean> 
                --> 
            </list> 
</property>

ActiveMQ B 
1.activemq.xml修改监听端口:

<transportConnectors> 
            <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> 
<!-- add &amp;wireFormat.maxInactivityDuration=0 --> 
            <transportConnector name="openwire" uri="tcp://0.0.0.0:61617?maximumConnections=1000&amp;wireformat.maxFrameSize=104857600&amp;wireFormat.maxInactivityDuration=0" discoveryUri="multicast://default"/> 
            <transportConnector name="amqp" uri="amqp://0.0.0.0:5673?maximumConnections=1000&amp;wireformat.maxFrameSize=104857600&amp;wireFormat.maxInactivityDuration=0"/>

</transportConnectors>

2.jetty.xml修改监听端口:

<property name="connectors"> 
            <list> 
                <bean id="Connector" class="org.eclipse.jetty.server.nio.SelectChannelConnector"> 
                    <property name="port" value="8166" /> 
                </bean> 
                <!-- 
                    Enable this connector if you wish to use https with web console 
                --> 
                <!-- 
                <bean id="SecureConnector" class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector"> 
                    <property name="port" value="8162" /> 
                    <property name="keystore" value="file:${activemq.conf}/broker.ks" /> 
                    <property name="password" value="password" /> 
                </bean> 
                --> 
            </list> 
</property>

Java测试程序代码: 
1.Producer:

import javax.jms.Connection; 
import javax.jms.DeliveryMode; 
import javax.jms.Destination; 
import javax.jms.JMSException; 
import javax.jms.MessageProducer; 
import javax.jms.Session; 
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory; 
   
public class ProducerTool { 
   
    private String subject = "TOOL.DEFAULT";    
   
    private Destination destination = null;    
   
    private Connection connection = null;    
   
    private Session session = null;    
   
    private MessageProducer producer = null;    
   
    // 初始化 
    private void initialize() throws JMSException, Exception {    
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("failover:(tcp://172.16.30.11:61616?wireFormat.maxInactivityDuration=0,tcp://172.16.30.11:61617?wireFormat.maxInactivityDuration=0)");    
        connection = connectionFactory.createConnection();    
        session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);   
        destination = session.createQueue(subject);    
        producer = session.createProducer(destination);    
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); 
         
    }    
   
    // 发送消息    
    public void produceMessage(String message) throws JMSException, Exception {    
        initialize();    
        TextMessage msg = session.createTextMessage(message);    
        connection.start();    
        System.out.println("Producer:->Sending message: " + message);    
        producer.send(msg);    
        System.out.println("Producer:->Message sent complete!");    
    }    
   
    // 关闭连接     
    public void close() throws JMSException {    
        System.out.println("Producer:->Closing connection");    
        if (producer != null)    
            producer.close();    
        if (session != null)    
            session.close();    
        if (connection != null)    
            connection.close();    
   }    
}

import javax.jms.Connection; 
import javax.jms.Destination; 
import javax.jms.JMSException; 
import javax.jms.Message; 
import javax.jms.MessageConsumer; 
import javax.jms.MessageListener; 
import javax.jms.Session; 
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory; 
   
public class ConsumerTool implements MessageListener {      
   
    private String subject = "TOOL.DEFAULT";    
   
    private Destination destination = null;    
   
    private Connection connection = null;    
   
    private Session session = null;    
   
    private MessageConsumer consumer = null;    
   
    // 初始化    
    private void initialize() throws JMSException, Exception {    
       ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("failover:(tcp://172.16.30.11:61616,tcp://172.16.30.11:61617)"); 
        connection = connectionFactory.createConnection();    
        session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);   
        destination = session.createQueue(subject);    
        consumer = session.createConsumer(destination);    
            
    }    
   
    // 消费消息       
    public void consumeMessage() throws JMSException, Exception {    
        initialize();    
        connection.start();    
            
        System.out.println("Consumer:->Begin listening...");    
        // 
        consumer.setMessageListener(this);    
        // Message message = consumer.receive();    
    }    
   
    // 关闭连接   
    public void close() throws JMSException {    
        System.out.println("Consumer:->Closing connection");    
        if (consumer != null)    
            consumer.close();    
        if (session != null)    
            session.close();    
        if (connection != null)    
            connection.close();    
    }    
   
    // 消息处理函数  
    public void onMessage(Message message) {    
        try {    
            if (message instanceof TextMessage) {    
                TextMessage txtMsg = (TextMessage) message;    
                String msg = txtMsg.getText();    
                System.out.println("Consumer:->Received: " + msg);    
            } else {    
                System.out.println("Consumer:->Received: " + message);    
            }    
        } catch (JMSException e) {    
            // TODO Auto-generated catch block    
            e.printStackTrace();    
        }    
    }    
}

2.Consumer:

import javax.jms.Connection; 
import javax.jms.Destination; 
import javax.jms.JMSException; 
import javax.jms.Message; 
import javax.jms.MessageConsumer; 
import javax.jms.MessageListener; 
import javax.jms.Session; 
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory; 
   
public class ConsumerTool implements MessageListener {      
   
    private String subject = "TOOL.DEFAULT";    
   
    private Destination destination = null;    
   
    private Connection connection = null;    
   
    private Session session = null;    
   
    private MessageConsumer consumer = null;    
   
    // 初始化    
    private void initialize() throws JMSException, Exception {    
       ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("failover:(tcp://172.16.30.11:61616,tcp://172.16.30.11:61617)"); 
        connection = connectionFactory.createConnection();    
        session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);   
        destination = session.createQueue(subject);    
        consumer = session.createConsumer(destination);    
            
    }    
   
    // 消费消息       
    public void consumeMessage() throws JMSException, Exception {    
        initialize();    
        connection.start();    
            
        System.out.println("Consumer:->Begin listening...");    
        // 
        consumer.setMessageListener(this);    
        // Message message = consumer.receive();    
    }    
   
    // 关闭连接   
    public void close() throws JMSException {    
        System.out.println("Consumer:->Closing connection");    
        if (consumer != null)    
            consumer.close();    
        if (session != null)    
            session.close();    
        if (connection != null)    
            connection.close();    
    }    
   
    // 消息处理函数  
    public void onMessage(Message message) {    
        try {    
            if (message instanceof TextMessage) {    
                TextMessage txtMsg = (TextMessage) message;    
                String msg = txtMsg.getText();    
                System.out.println("Consumer:->Received: " + msg);    
            } else {    
                System.out.println("Consumer:->Received: " + message);    
            }    
        } catch (JMSException e) {    
            // TODO Auto-generated catch block    
            e.printStackTrace();    
        }    
    }    
}

3.Main

import javax.jms.JMSException; 
   
public class Test {    
   
    /**   
     * @param args   
     */   
    public static void main(String[] args) throws JMSException, Exception { 
    
        
        ConsumerTool consumer = new ConsumerTool();    
        ProducerTool producer = new ProducerTool();    
        // 开始监听    
        consumer.consumeMessage();    
            
        // 延时500毫秒之后发送消息    
        Thread.sleep(500);    
        producer.produceMessage("Hello, world!");    
        producer.close();    
            
        // 延时500毫秒之后停止接受消息    
        Thread.sleep(500);    
        consumer.close();    
    
    }    
}

ActiveMQ A 启动界面:

ActiveMQ B 启动界面:

AMQ A先启动,先锁文件,当AMQ B启动是,不能锁文件,但会不断的监听等待。

运行Java Test程序日志:

10:22:43.745 INFO  [] org.apache.activemq.transport.failover.FailoverTransport - Successfully connected to tcp://172.16.30.11:61616 
Consumer:->Begin listening... 
10:22:45.623 INFO  [] org.apache.activemq.transport.failover.FailoverTransport - Successfully connected to tcp://172.16.30.11:61616?wireFormat.maxInactivityDuration=0 
Producer:->Sending message: Hello, world! 
Producer:->Message sent complete! 
Producer:->Closing connection 
Consumer:->Received: Hello, world! 
Consumer:->Closing connection

ActiveMQ A 管理界面:

异常处理:

配置好ActiveMQ后,前几次都启动成功。有一天启动时发现启动不成功,查看报错日志发现出现如下提示: 
Failed to start Apache ActiveMQ (localhost, ID:*-PC-*-*-0:1). Reason: java.io.IOException: Transport Connector could not be registered in JMX: Failed to bind to server socket: tcp://0.0.0.0:61616?maximumConnections=1000&wireformat.maxFrameSize=104857600 due to: java.net.BindException: Address already in use: JVM_Bind。

1.先去查看是不是端口被占用,用netstat -ano命令查看端口使用情况,发现没有端口被占用。 
2.在控制面板的服务里把正在运行的Internet Connection Sharing (ICS)为家庭和小型办公网络提供网络地址转换、寻址、名称解析和/或入侵保护服务关了,他占用着端口。 
3.把此服务关了后再启动ActvieMQ成功了。

ActiveMQ Cluster (ActiveMQ 集群) 配置的更多相关文章

  1. 基于zookeeper的activemq的主从集群配置

    项目,要用到消息队列,这里采用activemq,相对使用简单点.这里重点是环境部署. 0. 服务器环境 RedHat710.90.7.210.90.7.1010.90.2.102 1. 下载安装zoo ...

  2. ActiveMQ 高可用集群安装、配置(ZooKeeper + LevelDB)

    ActiveMQ 高可用集群安装.配置(ZooKeeper + LevelDB) 1.ActiveMQ 集群部署规划: 环境: JDK7 版本:ActiveMQ 5.11.1 ZooKeeper 集群 ...

  3. 关于ActiveMQ的几种集群配置

    ActiveMQ的几种集群配置. Queue consumer clusters 此集群让多个消费者同时消费一个队列,若某个消费者出问题无法消费信息,则未消费掉的消息将被发给其他正常的消费者,结构图如 ...

  4. ActiveMQ的几种集群配置

    ActiveMQ是一款功能强大的消息服务器,它支持许多种开发语言,例如Java, C, C++, C#等等.企业级消息服务器无论对服务器稳定性还是速度,要求都很高,而ActiveMQ的分布式集群则能很 ...

  5. ActiveMq+zookeeper+levelDB集群整合配置

    ActiveMq+zookeeper+levelDB集群整合配置 环境:linux系统,jdk1.7  三台linux系统电脑.我这里使用一台window,分别远程3台linux电脑.三台电脑的ip分 ...

  6. 基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

    一. zookeeper安装(集群):http://www.cnblogs.com/wangfajun/p/8692117.html  √ 二. ActiveMq配置: 1. ActiveMq集群部署 ...

  7. zookeeper+activemq高可用集群搭建

    一.准备工作: 准备三台机器:192.168.35.111192.168.35.112192.168.35.113 二.搭建zookeeper 三台机器上均要搭建zookeeper服务// 下载zoo ...

  8. ActiveMQ 事务、集群、持久订阅者、ActiveMQ监控

    JMS介绍 JMS是什么? JMS的全称Java Message Service,既Java消息服务. JMS是SUN提供的旨在统一各种MOM(Message-Oriented Middleware) ...

  9. 消息中间件-ActiveMQ高可用集群和持久化机制

    1.修改active.mq的xml文件 2.延时.调度消息 package com.study.mq.b1_message; import org.apache.activemq.ActiveMQCo ...

  10. Redis 3.0 Cluster集群配置

    Redis 3.0 Cluster集群配置 安装环境依赖 安装gcc:yum install gcc 安装zlib:yum install zib 安装ruby:yum install ruby 安装 ...

随机推荐

  1. linux定时任务-cron

    /sbin/service crond start //启动服务 /sbin/service crond stop //关闭服务 /sbin/service crond restart //重启服务 ...

  2. 你竟然在公钥中下毒!——如何在RSA公钥中添加后门

    原文:http://www.hackdig.com/?01/hack-17893.htm 分享到: 当我知道它是如何运行时,我惊得下巴都掉了.这是一个非常简单的手法,但这篇文章会颠覆你之前对RSA的看 ...

  3. Codeforces 2B The least round way(dp求最小末尾0)

    题目链接:http://codeforces.com/problemset/problem/2/B 题目大意: 给你一个nxn的矩形,找到一条从左上角到右下角的路径,使得该路径上所有数字的乘积的末尾0 ...

  4. HDU 2819 Swap(行列式性质+最大匹配)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2819 题目大意:给你一个n*n的01矩阵,问是否可以通过任意交换整行或者整列使得正对角线上都是1. ...

  5. web项目引入extjs小例子

    一个新的项目,前端用extjs实现!分享一下extjs开发的准备工作! 首先去下载extjs的资源包,这里我是随便在网上下载的! 打开之后 ,目录是这样的! 需要关注的几个文件夹: builds:压缩 ...

  6. MySQL学习笔记:floor、round —— 取整

    在MySQL中做数值处理,需要取整或者四舍五入. floor:函数只返回整数部分,小数部分舍弃: round:函数四舍五入: END 2018-05-29 11:31:22

  7. Ubuntu Touch On Nexus4 Manual Install (手动安装) under Gentoo

    Table of Contents 1. 准备工作: 2. Saucy Salamander 3. 刷入 最新 版Touch 最近手里的 Nexus 4 手机一直闲置,它的配置要比我六年前买的笔记本还 ...

  8. Spark-Streaming总结

    文章出处:http://www.cnblogs.com/haozhengfei/p/e353daff460b01a5be13688fe1f8c952.html Spark_总结五 1.Storm 和 ...

  9. zabbix监控多实例tomcat--不使用JMX

    https://blog.csdn.net/nisan892541/article/details/47727967

  10. 【LOJ】#2587. 「APIO2018」铁人两项

    题解 学习了圆方树!(其实是复习了Tarjan求点双) 我又双叒叕忘记了tarjan点双一个最重要,最重要的事情! 就是--假如low[v] >= dfn[u],我们就找到了一个点双,开始建立方 ...