ActiveMQ集群安装

一、ActiveMQ集群的简单介绍

从 ActiveMQ 5.9 开始,ActiveMQ 的集群实现方式取消了传统的 Master-Slave 方式,增加了基于ZooKeeper + LevelDB 的 Master-Slave 实现方式,
其他两种方式目录共享和数据库共享依然存在。
三种集群方式的对比:
(1)基于共享文件系统(KahaDB,默认):
<persistenceAdapter> <kahaDB directory="${activemq.data}/kahadb"/> </persistenceAdapter>
(2)基于 JDBC:
<bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/amq?relaxAutoCommit=true"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="maxActive" value="20"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
<persistenceAdapter>
<jdbcPersistenceAdapter dataDirectory="${activemq.data}" dataSource="#mysql-ds" createTablesOnStartup="false"/> </persistenceAdapter>
(3)基于可复制的 LevelDB(本教程采用这种集群方式):
LevelDB 是 Google 开发的一套用于持久化数据的高性能类库。LevelDB 并不是一种服务,用户需要自行实现 Server。是单进程的服务,能够处理十亿级别规模 Key-Value 型数据,
占用内存小。
<persistenceAdapter>
<replicatedLevelDB directory="${activemq.data}/leveldb" replicas="3" bind="tcp://0.0.0.0:62621" zkAddress="localhost:2181,localhost:2182,localhost:2183" hostname="localhost" zkPath="/activemq/leveldb-stores"/> </persistenceAdapter>
本节课程主要讲解基于 ZooKeeper 和 LevelDB 搭建 ActiveMQ 集群。集群仅提供主备方式的高可用集群功能,避免单点故障,没有负载均衡功能。
官方文档:http://activemq.apache.org/replicated-leveldb-store.html
集群原理图

15882615.png

高可用的原理:使用 ZooKeeper(集群)注册所有的ActiveMQ Broker。只有其中的一个Broker可以提供服务,被视为 Master,其他的 Broker 处于待机状态,被视为 Slave。
如果 Master 因故障而不能提供服务,ZooKeeper 会从 Slave 中选举出一个 Broker 充当 Master。
Slave 连接 Master 并同步他们的存储状态,Slave 不接受客户端连接。所有的存储操作都将被复制到连接至 Master 的 Slaves。如果 Master 宕了,
得到了最新更新的 Slave 会成为 Master。故障节点在恢复后会重新加入到集群中并连接 Master 进入 Slave 模式。
所有需要同步的 disk 的消息操作都将等待存储状态被复制到其他法定节点的操作完成才能完成。所以,如果你配置了 replicas=3,那么法定大小是(3/2)+1=2。
Master 将会存储并更新然后等待 (2-1)=1 个Slave 存储和更新完成,才汇报 success。至于为什么是 2-1,熟悉 Zookeeper 的应该知道,有一个 node要作为观擦者存在。
当一个新的 Master 被选中,你需要至少保障一个法定 node 在线以能够找到拥有最新状态的 node。这个 node 可以成为新的 Master。
因此,推荐运行至少 3 个 replica nodes,以防止一个 node失败了,服务中断。

二、集群环境的搭建
1、ActiveMQ集群环境规划
环境:CentOS6.5、JDK1.7
版本:ActiveMQ 5.11.5
zookeeper集群环境:
192.168.31.154:2181
192.168.31.117:2182
192.168.31.146:2183
(zookeeper集群的安装可参考:http://www.jianshu.com/p/1dfcc020aa9c
端口的规划要注意是否已经被占用
主机 集群端口 消息端口 管控台端口 节点安装目录
192.168.31.154 62621 51511 8161
192.168.31.117 62622 51512 8162
192.168.31.14662623 51513 8163

2、切换至root用户,在各个服务器的防火墙打开对应的端口
# vi /etc/sysconfig/iptables
192.168.31.154中增加:
## activemq -A INPUT -m state --state NEW -m tcp -p tcp --dport 62621 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 51511 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 8161 -j ACCEPT
192.168.31.117中增加:
## activemq -A INPUT -m state --state NEW -m tcp -p tcp --dport 62622 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 51512 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 8162 -j ACCEPT
192.168.31.146中增加:
## activemq -A INPUT -m state --state NEW -m tcp -p tcp --dport 62623 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 51513 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 8163 -j ACCEPT
增加完后,重启防火墙:
# service iptables restart

3、分别在三台机器中创建/home/dreyer/activemq目录,并上传apache-activemq-5.11.1-bin.tar.gz到该目录下
$ mkdir /home/dreyer04/activemq

4、解压并按节点进行重命名
$ tar -zxvf apache-activemq-5.11.1-bin.tar.gz
$ mv apache-activemq-5.11.1 node-0X(X代表节点号1、2、3,下同)

5、修改管控台端口(默认为8161),在/conf/jetty.xml中修改
$ vi /home/dreyer04/activemq/node-02/conf/jetty.xml

node-01管控台端口:
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start"> <property name="host" value="0.0.0.0"/> <property name="port" value="8161"/> </bean>
node-02管控台端口
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start"> <property name="host" value="0.0.0.0"/> <property name="port" value="8162"/> </bean>
node-03管控台端口
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start"> <property name="host" value="0.0.0.0"/> <property name="port" value="8163"/> </bean>

6、集群配置
在3个ActiveMQ节点中配置/conf/activemq.xml中的持久化配置。修改其中的bind、zkAddress、hostname和zkPath。注意:每个ActiveMQ的BrokerName必须相同,否则不能加入集群。
$ vi /home/dreyer03/activemq/node-01/conf/activemq.xml
(找到brokerName属性并修改,删除原先的persistenceAdapter节点,用下面新的替代)
参数说明:
directory:数据目录
replicas:复制节点数
bind:集群通讯的端口
zkAddres:zookeeper配置
hostname:主机名,在/etc/hosts中做的映射
zkPath:zookeeper数据路径

node-1的持久化配置:
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="MyMQ" dataDirectory="${activemq.data}"> <persistenceAdapter> <replicatedLevelDB directory="${activemq.data}/leveldb" replicas="3" bind="tcp://0.0.0.0:62621" zkAddress="192.168.31.154:2181,192.168.31.117:2182,192.168.31.146:2183" hostname="dreyer-zk-01" zkPath="/activemq/leveldb-stores" /> </persistenceAdapter> </broker>
node-01中的消息端口配置(默认为61611,现改为51511):
<transportConnectors> <transportConnector name="openwire" uri="tcp://0.0.0.0:51511?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors>

node-02的持久化配置
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="MyMQ" dataDirectory="${activemq.data}"> <persistenceAdapter> <replicatedLevelDB directory="${activemq.data}/leveldb" replicas="3" bind="tcp://0.0.0.0:62622" zkAddress="192.168.31.154:2181,192.168.31.117:2182,192.168.31.146:2183" hostname="dreyer-zk-02" zkPath="/activemq/leveldb-stores" /> </persistenceAdapter> </broker>
node-02中的消息端口配置(默认为61616,现改为51512):
<transportConnectors> <transportConnector name="openwire" uri="tcp://0.0.0.0:51512?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors>

node-03的持久化配置
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="MyMQ" dataDirectory="${activemq.data}"> <persistenceAdapter> <replicatedLevelDB directory="${activemq.data}/leveldb" replicas="3" bind="tcp://0.0.0.0:62623" zkAddress="192.168.31.154:2181,192.168.31.117:2182,192.168.31.146:2183" hostname="dreyer-zk-03" zkPath="/activemq/leveldb-stores" /> </persistenceAdapter> </broker>
node-03中的消息端口配置(默认为61616,现改为51513):
<transportConnectors> <transportConnector name="openwire" uri="tcp://0.0.0.0:51513?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors>

7、按顺序启动3个ActiveMQ节点
$ /home/dreyer03/activemq/node-01/bin/activemq start
$ /home/dreyer04/activemq/node-02/bin/activemq start
$ /home/dreyer05/activemq/node03/bin/activemq start
监听日志:
$ tail -f /home/dreyer03/activemq/node-01/data/activemq.log
$ tail -f /home/dreyer04/activemq/node-02/data/activemq.log
$ tail -f /home/dreyer05/activemq/node03/data/activemq.log

8、集群的节点状态分析
下载Zooinspector,这是一款zookeeper的监控工具
下载后打开build目录下的zookeeper-dev-ZooInspector,点击绿色的运行按钮,输入zookeeper的连接信息,点击OK即可

RKJT5NYVKCILEYNCYK~VA@D.jpg
U`Z`UQUH%88ZL8G%%Z715NR.png

![1LP91~LNPCI]6N3HD4M)PVW.png](http://upload-images.jianshu.io/upload_images/2591074-743409bd0bf5217e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
从图中我们可以看到ActiveMQ有三个节点,分别是0000000000、0000000001、0000000002
第一张图的elected的值不为null,说明这个节点是master,其他两个elected为null的节点为slave。

9、集群的可用性测试(配合应用程序,略)
ActiveMQ 的客户端只能访问 Master 的 Broker,其他处于 Slave 的 Broker 不能访问。所以客户端连接 Broker 应该使用 failover(失效转移)协议。
failover:(tcp://192.168.1.154:51511,tcp://192.168.31.117:51512,tcp://192.168.31.146:51513)?randomize=false
附项目中mq.properties配置信息
## MQ
mq.brokerURL=failover:(tcp://192.168.31.154:51511,tcp://192.168.31.117:51512,tcp://192.168.31.146:51513)?randomize=false
mq.userName=admin
mq.password=admin
mq.pool.maxConnetcions=10
##queueName
queueName=dreyer.mq.v1

10、集群的高可用性
当一个 ActiveMQ 节点挂掉,或者一个 ZooKeeper 节点挂掉,ActiveMQ 服务依然正常运转。当主节点挂掉,ActiveMQ会很快又选举出一个主节点,如果仅剩一个 ActiveMQ 节点,因为不能选举 Master,ActiveMQ 不能正常运转;同样的,如果 ZooKeeper 仅剩一个节点活动,不管 ActiveMQ 各节点是否存活,ActiveMQ 也不能正常提供服务。
(ActiveMQ 集群的高可用,依赖于 ZooKeeper 集群的高可用 ,整个zookeeper集群挂掉之后,需要对ActiveMQ进行重启)

11、设置ActiveMQ开机启动
切换至root用户编辑/etc/rc.local文件
# vi /etc/rc.local
三台机器分别添加以下脚本(脚本大意:切换至dreyer03用户,执行xx目录下的启动脚本)
su - dreyer03 -c '/home/dreyer03/activemq/node-01/bin/activemq start'
su - dreyer04 -c '/home/dreyer04/activemq/node-02/bin/activemq start'
su - dreyer05 -c '/home/dreyer05/activemq/node-03/bin/activemq start'

最后,附上官方文档的一则警告,请使用者注意。replicatedLevelDB 不支持延迟或者计划任务消息。这 些消息存储在另外的 LevelDB 文件中,如果使用延迟或者计划任务消息,将不会复制到 slave Broker 上, 不能实现消息的高可用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容