在http://blog.csdn.net/zuolj/article/details/53149015中介绍了ActiveMQ的zookeeper+levelDB的高可用架构。
我在单机上部署了一个ActiveMQ基于zookeeper的集群,记录一下部署过程。
部署的集群的整体架构图如下:
zookeeper集群部署
ActiveMQ的高可用集群基于Zookeeper的高可用集群,所以要先部署Zookeeper集群。
1.zookeeper下载地址:http://zookeeper.apache.org/releases.html
2.下载后解压到当前用户的home目录,复制三份(因为需要至少需要三个zookeeper实例才能保证zookeeper本身的高可用),分别标识为zookeeper-3.4.6_(1)、zookeeper-3.4.6_(2)、zookeeper-3.4.6_(3)
user@ cp -r zookeeper-3.4.6 zookeeper-3.4.6_(1)
user@ cp -r zookeeper-3.4.6 zookeeper-3.4.6_(2)
user@ cp -r zookeeper-3.4.6 zookeeper-3.4.6_(3)
3.在各zookeeper节点目录下创建以下目录:
user@ cd zookeeper-3.4.6_(x)
user@ mkdir data
user@ mkdir logs
4.将 zookeeper-3.4.6_(x)/conf目录下的zoo_sample.cfg文件拷贝一份,命名为zoo.cfg:
user@ cp zoo_sample.cfg zoo.cfg
5.修改 zoo.cfg 配置文件
zookeeper-3.4.6_(1)的配置(zookeeper-3.4.6_(1)/conf/zoo.cfg)如下:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/ $USER_HOME/zookeeper-3.4.6_(1)/data
dataLogDir=/$USER_HOME/zookeeper-3.4.6_(1)/logs
clientPort=2181
server.1=10.10.24.140:2881:3881
server.2=10.10.24.140:2882:3882
server.3=10.10.24.140:2883:3883
zookeeper-3.4.6_(2)的配置(zookeeper-3.4.6_(2)/conf/zoo.cfg)如下:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/ $USER_HOME/zookeeper-3.4.6_(2)/data
dataLogDir=/$USER_HOME/zookeeper-3.4.6_(2)/logs
clientPort=2182
server.1=10.10.24.140:2881:3881
server.2=10.10.24.140:2882:3882
server.3=10.10.24.140:2883:3883
zookeeper-3.4.6_(3)的配置(ookeeper-3.4.6_(3)/conf/zoo.cfg)如下:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/ $USER_HOME/zookeeper-3.4.6_(3)/data
dataLogDir=/$USER_HOME/zookeeper-3.4.6_(3)/logs
clientPort=2183
server.1=10.10.24.140:2881:3881
server.2=10.10.24.140:2882:3882
server.3=10.10.24.140:2883:3883
参数说明:
clientPort=2181
clientPort这个端口就是客户端(应用程序)连接Zookeeper服务器的端口,Zookeeper 会监听这个端 口接受客户端的访问请求。
server.A=B:C:D
A 是一个数字,表示这个是第几号服务器;
B 是这个服务器的IP地址(或者是与IP地址做了映射的主机名);
C 第一个端口用来集群成员的信息交换,表示这个服务器与集群中的 Leader 服务器交换信息的端口;
D 是在leader挂掉时专门用来进行选举 leader 所用的端口。
6.在dataDir=/zookeeper-3.4.6_(x)/data下创建 myid 文件
user@ cd data
user@ vi myid
x(x为数字,哪个zookeeper节点就设置为哪个,这里应该是1,2,3)
7.分别进入三个zookeeper中的bin,启动并查看zookeeper:
user@ ./zkServer.sh start
user@ tail -f zookeeper.out
如果启动失败,检查是否开启的防火墙没有开发端口,开启防火墙,要把端口打开:
user@ vi /etc/sysconfig/iptables
-A INPUT -m state –state NEW -m tcp -p tcp –dport 218X -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 288X -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 388X -j ACCEPT
user@ service iptables restart
ActiveMQ配置
1.首先分别更改三个MQ的端口,涉及到的配置文件为apache-activemq-5.12.1/conf
中的activemq.xml,jetty.xml。
jetty.xml配置监控端口 节点1: <property name=”port” value=”8161”/> 节点2: <property name=”port” value=”7161”/> 节点3: <property name=”port” value=”6161”/> |
activemq.xml配置消息端口 将broker2的broker3的端口修改为: |
<!-- broker2 -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:51616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
121
<transportConnector name="amqp" uri="amqp://0.0.0.0:4673?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
122
<transportConnector name="stomp" uri="stomp://0.0.0.0:51613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
123
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:2883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<!-- broker3 -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:41616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
121
<transportConnector name="amqp" uri="amqp://0.0.0.0:3673?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
122
<transportConnector name="stomp" uri="stomp://0.0.0.0:41613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
123
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1884?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
2.继续更改activema.xml文件,与zookeeper关联上。
<!-- broker1 -->
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="broker" dataDirectory="${activemq.data}"/>
<persistenceAdapter>
<replicatedLevelDB
directory="${activemq.data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:61619?"
zkAddress="localhost:2181,localhost:2182,localhost:2183"
hostname="127.0.0.1"
zkPath="/activemq/leveldb-stores"/>
</persistenceAdapter>
</broker>
<!-- broker2 -->
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="broker" dataDirectory="${activemq.data}"/>
<persistenceAdapter>
<replicatedLevelDB
directory="${activemq.data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:61618?"
zkAddress="localhost:2181,localhost:2182,localhost:2183"
hostname="127.0.0.1"
zkPath="/activemq/leveldb-stores"/>
</persistenceAdapter>
</broker>
<!-- broker3 -->
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="broker" dataDirectory="${activemq.data}"/>
<persistenceAdapter>
<replicatedLevelDB
directory="${activemq.data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:61617?"
zkAddress="localhost:2181,localhost:2182,localhost:2183"
hostname="127.0.0.1"
zkPath="/activemq/leveldb-stores"/>
</persistenceAdapter>
</broker>
注意修改persistenceAdapter节点
- replicas:集群中节点的数量,默认配置3
- bind:当这个节点成为主节点后,就会默认绑定当前IP和端口,用于与其他slave节点通信
- zkAddress:三台zookeeper的服务ip和端口,用逗号隔开
- zkPath:默认不用改
- hostname:填写三台zookeeper可以互相访问的地址,由于配置的是同一台机器,所以写的127.0.0.1,如果部署的是三台内网,这里就写相应的那台机器的内网IP。
注意:每个 ActiveMQ 的 BrokerName 必须相同,否则不能加入集群。
3.按顺序启动 3 个 ActiveMQ 节点:
user@ sudo /$USER_HOME/activemq-1/bin/activemq start
user@ sudo /$USER_HOME/activemq-2/bin/activemq start
user@ sudo /$USER_HOME/activemq-3/bin/activemq start
客户端连接
ActiveMQ 的客户端只能访问Master的Broker,其他处于Slave的Broker不能访问。所以客户端连接Broker应该使用failover协议。
配置为:
failover:(tcp://10.10.24.140:61616,tcp://10.10.24.140:51616,tcp://10.10.24.140:41616)?randomize=false
异常测试
开启一个producer每隔1s发送一个消息,此时broker1作为master对外服务,producer连接上broker1,10s后手动关闭broker1实例,producer可以自动切换到新的master broker上继续进行发送消息的操作,且查看新的master节点,前10s发送的消息没有丢失。