ActiveMQ基于LevelDB的Zookeeper高可用集群
来源:互联网 发布:网络约车平台架构图 编辑:程序博客网 时间:2024/05/19 16:47
是对ActiveMQ进行高可用的一种有效的解决方案,高可用的原理:使用ZooKeeper(集群)注册所有的ActiveMQ Broker。只有其中的一个Broker可以对外提供服务(也就是Master节点),其他的Broker处于待机状态,被视为Slave。如果Master因故障而不能提供服务,则利用ZooKeeper的内部选举机制会从Slave中选举出一个Broker充当Master节点,继续对外提供服务。
官网文档如下:
http://activemq.apache.org/replicated-leveldb-store.html
每台服务器做如下操作
cd /usr/localwget http://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.8/zookeeper-3.4.8.tar.gztar -zxvf zookeeper-3.4.8.tar.gzcp /usr/local/zookeeper-3.4.8/conf/zoo_sample.cfg /usr/local/zookeeper-3.4.8/conf/zoo.cfg
完成上述操作后,修改zoo.cfg配置文件成如下
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/var/zookeeper/data dataLogDir=/var/zookeeper/log clientPort=2181 #2287为peer通信端口,3387为选举端口 server.1=192.168.1.101:2287:3387 server.2=192.168.1.102:2287:3387 server.3=192.168.1.103:2287:3387
每个ZooKeeper的instance,都需要设置独立的数据存储目录、日志存储目录,所以dataDir节点对应的目录,需要手动先创建好
mkdir /var/zookeepermkdir /var/zookeeper/datamkdir /var/zookeeper/logtouch /var/zookeeper/data/myid
另外还有一个非常关键的设置,在每个zk server配置文件的dataDir所对应的目录下,必须创建一个名为myid的文件,其中的内容必须与zoo.cfg中server.x 中的x相同,即:
- 192.168.1.101 服务器 /var/zookeeper/data/myid中的内容为1,对应server.1中的1
- 192.168.1.102 服务器 /var/zookeeper/data/myid中的内容为2,对应server.2中的2
- 192.168.1.103 服务器 /var/zookeeper/data/myid中的内容为3,对应server.3中的3
/usr/local/zookeeper-3.4.8/bin/zkServer.sh start /usr/local/zookeeper-3.4.8/bin/zkServer.sh stop/usr/local/zookeeper-3.4.8/bin/zkServer.sh status
验证集群状态
--MasterZooKeeper JMX enabled by defaultUsing config: /usr/local/zookeeper-3.4.8/bin/../conf/zoo.cfgMode: leader
--SlaveZooKeeper JMX enabled by defaultUsing config: /usr/local/zookeeper-3.4.8/bin/../conf/zoo.cfgMode: follower
touch /etc/init.d/zookeeper chmod +x /etc/init.d/zookeeper
编辑zookeeper 文件如下内容
#!/bin/bash #chkconfig:2345 20 90 #description:zookeeper #processname:zookeeper case $1 in start) /usr/local/zookeeper-3.4.8/bin/zkServer.sh start;; stop) /usr/local/zookeeper-3.4.8/bin/zkServer.sh stop;; status) /usr/local/zookeeper-3.4.8/bin/zkServer.sh status;; restart) /usr/local/zookeeper-3.4.8/bin/zkServer.sh restart;; *) echo "require start|stop|status|restart";; esac
添加服务
chkconfig --add zookeeper
设置开机启动
chkconfig --level 35 zookeeper on
查看是否设置成功
[root@localhost ~]# chkconfig --list | grep zookeeperzookeeper 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭
cd /usr/local/zookeeper-3.4.8/bin ./zkCli.sh -timeout 5000 -server localhost:2181Connecting to localhost:21812017-04-22 08:21:34,876 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.8--1, built on 02/06/2016 03:18 GMT2017-04-22 08:21:34,884 [myid:] - INFO [main:Environment@100] - Client environment:host.name=localhost2017-04-22 08:21:34,884 [myid:] - INFO [main:Environment@100] - Client environment:java.version=1.8.0_1112017-04-22 08:21:34,896 [myid:] - INFO [main:Environment@100] - Client environment:java.vendor=Oracle Corporation2017-04-22 08:21:34,896 [myid:] - INFO [main:Environment@100] - Client environment:java.home=/usr/local/jdk1.8.0_111/jre2017-04-22 08:21:34,897 [myid:] - INFO [main:Environment@100] - Client environment:java.class.path=/usr/local/zookeeper-3.4.8/bin/../build/classes:/usr/local/zookeeper-3.4.8/bin/../build/lib/*.jar:/usr/local/zookeeper-3.4.8/bin/../lib/slf4j-log4j12-1.6.1.jar:/usr/local/zookeeper-3.4.8/bin/../lib/slf4j-api-1.6.1.jar:/usr/local/zookeeper-3.4.8/bin/../lib/netty-3.7.0.Final.jar:/usr/local/zookeeper-3.4.8/bin/../lib/log4j-1.2.16.jar:/usr/local/zookeeper-3.4.8/bin/../lib/jline-0.9.94.jar:/usr/local/zookeeper-3.4.8/bin/../zookeeper-3.4.8.jar:/usr/local/zookeeper-3.4.8/bin/../src/java/lib/*.jar:/usr/local/zookeeper-3.4.8/bin/../conf:.:/usr/local/jdk1.8.0_111/lib2017-04-22 08:21:34,898 [myid:] - INFO [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib2017-04-22 08:21:34,898 [myid:] - INFO [main:Environment@100] - Client environment:java.io.tmpdir=/tmp2017-04-22 08:21:34,898 [myid:] - INFO [main:Environment@100] - Client environment:java.compiler=<NA>2017-04-22 08:21:34,898 [myid:] - INFO [main:Environment@100] - Client environment:os.name=Linux2017-04-22 08:21:34,899 [myid:] - INFO [main:Environment@100] - Client environment:os.arch=amd642017-04-22 08:21:34,899 [myid:] - INFO [main:Environment@100] - Client environment:os.version=2.6.32-431.el6.x86_642017-04-22 08:21:34,899 [myid:] - INFO [main:Environment@100] - Client environment:user.name=root2017-04-22 08:21:34,902 [myid:] - INFO [main:Environment@100] - Client environment:user.home=/root2017-04-22 08:21:34,903 [myid:] - INFO [main:Environment@100] - Client environment:user.dir=/usr/local/zookeeper-3.4.8/bin2017-04-22 08:21:34,912 [myid:] - INFO [main:ZooKeeper@438] - Initiating client connection, connectString=localhost:2181 sessionTimeout=5000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@531d72caWelcome to ZooKeeper!2017-04-22 08:21:35,003 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)JLine support is enabled2017-04-22 08:21:35,241 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@876] - Socket connection established to localhost/127.0.0.1:2181, initiating session2017-04-22 08:21:35,279 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1299] - Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x15b92ff5d4b0002, negotiated timeout = 5000WATCHER::WatchedEvent state:SyncConnected type:None path:null[zk: localhost:2181(CONNECTED) 0]
执行ls /,可以看到根下已有的目录结构,新搭建的服务只有/zookeeper
cd /usr/localwget http://mirrors.noc.im/apache//activemq/5.13.2/apache-activemq-5.13.2-bin.tar.gztar -zxvf apache-activemq-5.13.2-bin.tar.gz
设置开机脚本文件
ln -s /usr/local/apache-activemq-5.13.2/bin/activemq /etc/init.d/activemqvi /etc/init.d/activemq
在第二行插入如下两行语句
# chkconfig: 345 63 37 # description: Auto start ActiveMQ
chkconfig --add activemq chkconfig --level 35 activemq on[root@localhost ~]# chkconfig --list | grep activemq activemq 0:关闭 1:关闭 2:关闭 3:启用 4:启用 5:启用 6:关闭
操作ActiveMQ
service activemq startservice activemq stopservice activemq restart
检测8161、61616端口是否在监听
[root@localhost ~]# netstat -tunpl | grep 8161tcp 0 0 :::8161 :::* LISTEN 1412/java [root@localhost ~]# netstat -tunpl | grep 61616tcp 0 0 :::61616 :::* LISTEN 1412/java
mq安装路径下的conf/activemq.xml进行mq的brokerName,并且每个节点名称都必须相同。
brokerName=”activemq-cluster”(三个节点都需要修改)
释掉适配器中的kahadb
添加新的leveldb配置如下(三个节点都需要修改):
--NODE1<persistenceAdapter> <!-- <kahaDB directory="${activemq.data}/kahadb"/> --> <replicatedLevelDB directory="${activemq.data}/leveldb" replicas="3" bind="tcp://0.0.0.0:61619" zkAddress="192.168.1.101:2181,192.168.1.102:2181,192.168.1.103:2181" hostname="192.168.1.101" zkPath="/activemq/leveldb-stores" /></persistenceAdapter>--NODE2<persistenceAdapter> <!-- <kahaDB directory="${activemq.data}/kahadb"/> --> <replicatedLevelDB directory="${activemq.data}/leveldb" replicas="3" bind="tcp://0.0.0.0:61619" zkAddress="192.168.1.101:2181,192.168.1.102:2181,192.168.1.103:2181" hostname="192.168.1.102" zkPath="/activemq/leveldb-stores" /></persistenceAdapter>--NODE3<persistenceAdapter> <!-- <kahaDB directory="${activemq.data}/kahadb"/> --> <replicatedLevelDB directory="${activemq.data}/leveldb" replicas="3" bind="tcp://0.0.0.0:61619" zkAddress="192.168.1.101:2181,192.168.1.102:2181,192.168.1.103:2181" hostname="192.168.1.103" zkPath="/activemq/leveldb-stores" /></persistenceAdapter>
到此为止,我们的activemq集群环境已经搭建完毕!
分别查看三台服务器的日志信息:
#192.168.1.101tail -f /usr/local/apache-activemq-5.13.2/data/activemq.log#192.168.1.102tail -f /usr/local/apache-activemq-5.13.2/data/activemq.log#192.168.1.103tail -f /usr/local/apache-activemq-5.13.2/data/activemq.log
如果不报错,我们的集群启动成功
使用ZooKeeper(集群)注册所有的ActiveMQ Broker。只有其中的一个Broker可以提供服务,被视为Master,其他的 Broker 处于待机状态,被视为Slave。
如果Master因故障而不能提供服务,Zookeeper会从Slave中选举出一个Broker充当Master。Slave连接Master并同步他们的存储状态,Slave不接受客户端连接。所有的存储操作都将被复制到 连接至 Master的Slaves。
如果Master宕了,得到了最新更新的Slave会成为Master。故障节点在恢复后会重新加入到集群中并连接Master进入Slave模式。
当集群运行时,只有一个为Master可用,控制台可访问,有队列,订阅主题消息,而Slave上没有,只有在Master宕机时,重新选举的Master从源Master拷贝消息,Slave与新的Master连接,同步leveldb索引信息。
#集群的brokerUrl配置failover:(tcp://192.168.1.101:61616,tcp://192.168.1.102:61616,tcp://192.168.1.103:61616)?Randomize=false
在Eclipse环境下安装ZooKeeper状态查看相关的插件步骤如下:
1. 在 Eclipse 菜单打开Help -> Install New Software… 2. 添加 url http://www.massedynamic.org/eclipse/updates/ 3. 选择插件并安装运行 4. 在 Eclipse 菜单打开Window->Show View->Other…->ZooKeeper 3.2.2 5. 连接ZK 输入正在运行的ZK server 地址和端口
连接成功后就就可以在Eclipse里查看ZK Server里的节点信息。如下所示:
单点的ActiveMQ作为企业应用无法满足高可用和集群的需求,所以ActiveMQ提供了master-slave、broker cluster等多种部署方式,但通过分析多种部署方式之后我认为需要将两种部署方式相结合才能满足我们公司分布式和高可用的需求,所以后面就重点将解如何将两种部署方式相结合。
这种方式Slave的个数没有限制,哪个ActiveMQ实例先获取共享文件的锁,那个实例就是Master,其它的ActiveMQ实例就是Slave,当当前的Master失效,其它的Slave就会去竞争共享文件锁,谁竞争到了谁就是Master。此模式结构图如下:
与shared file system方式类似,只是共享的存储介质由文件系统改成了数据库而已。
这种主备方式是ActiveMQ5.9以后才新增的特性,使用zooKeeper协调选择一个node作为Master。被选择的Master broker node开启并接受客户端连接。
其他node转入Slave模式,连接Master并同步他们的存储状态。Slave不接受客户端连接。所有的存储操作都将被复制到连接至Master的Slaves。
如果Master死了,得到了最新更新的slave被允许成为Master。fialed node能够重新加入到网络中并连接Master进入Slave node。所有需要同步的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失败了,服务中断。
可以看到Master-Slave的部署方式虽然解决了高可用的问题,但不支持负载均衡,Broker-Cluster解决了负载均衡,但当其中一个Broker突然宕掉的话,那么存在于该Broker上处于Pending状态的message将会丢失,无法达到高可用的目的。
由于目前ActiveMQ官网上并没有一个明确的将两种部署方式相结合的部署方案,所以我尝试者把两者结合起来部署:
在activemq.xml文件中静态指定Broker需要建立桥连接的其他Broker:
<networkConnectors> <networkConnector uri="static:(tcp://192.168.1.104:61616,tcp://192.168.1.105:61616,tcp://192.168.1.106:61616)" duplex="false"/> <networkConnector uri="static:(tcp://192.168.1.107:61616,tcp://192.168.1.108:61616,tcp://192.168.1.109:61616)" duplex="false"/></networkConnectors>
<networkConnectors> <networkConnector uri="static:(tcp://192.168.1.101:61616,tcp://192.168.1.102:61616,tcp://192.168.1.103:61616)" duplex="false"/> <networkConnector uri="static:(tcp://192.168.1.107:61616,tcp://192.168.1.108:61616,tcp://192.168.1.109:61616)" duplex="false"/></networkConnectors>
<networkConnectors> <networkConnector uri="static:(tcp://192.168.1.101:61616,tcp://192.168.1.102:61616,tcp://192.168.1.103:61616)" duplex="false"/> <networkConnector uri="static:(tcp://192.168.1.104:61616,tcp://192.168.1.105:61616,tcp://192.168.1.106:61616)" duplex="false"/></networkConnectors>
在activemq.xml文件中不直接指定Broker需要建立桥连接的其他Broker,由activemq在启动后动态查找:
<networkConnectors> <networkConnectoruri="multicast://default" dynamicOnly="true" networkTTL="3" prefetchSize="1" decreaseNetworkConsumerPriority="true" /></networkConnectors>
<networkConnectors> <networkConnectoruri="multicast://default" dynamicOnly="true" networkTTL="3" prefetchSize="1" decreaseNetworkConsumerPriority="true" /></networkConnectors>
<networkConnectors> <networkConnectoruri="multicast://default" dynamicOnly="true" networkTTL="3" prefetchSize="1" decreaseNetworkConsumerPriority="true" /></networkConnectors>
- ActiveMQ基于LevelDB的Zookeeper高可用集群
- JMS之——ActiveMQ高可用集群安装、配置(基于ZooKeeper + LevelDB的伪集群)
- JMS之——ActiveMQ高可用集群安装、配置(基于ZooKeeper + LevelDB的伪集群)
- activemq的高可用(zookeeper+leveldb)主从集群
- 基于zookeeper+levelDB的ActiveMQ集群
- ActiveMQ 高可用集群(ZooKeeper + LevelDB + Static discovery)
- activemq - 集群 - 基于zookeeper的levelDB集群方式
- 分布式架构学习之:028--ActiveMQ高可用集群(zookeeper+leveldb)安装、配置、高可用测试
- 分布式架构学习之:ActiveMQ高可用集群(zookeeper+leveldb)安装、配置、高可用测试
- ActiveMQ高可用架构(zookeeper+levelDB)
- 基于zookeeper+leveldb搭建activemq集群
- 基于zookeeper+leveldb搭建activemq集群
- 基于zookeeper+leveldb搭建activemq集群
- 基于zookeeper+leveldb搭建activemq集群
- 基于zookeeper+leveldb搭建activemq集群【转】
- 基于zookeeper+leveldb搭建activemq集群
- ActiveMQ学习笔记04 - 基于LevelDB的高可用
- ActiveMQ常见的高可用架构模式及使用LevelDB、ZooKeeper进行高可用消息架构
- Android实现推送方式解决方案
- 系统的简单注解
- centos下搭建git服务器
- [牛客]访问单个节点的删除练习题
- sevlet 与filter区别
- ActiveMQ基于LevelDB的Zookeeper高可用集群
- android使用shape stroke描边只保留底部
- CSS Sprites+CSS3 Icon Font
- Linux下使用du查看文件夹大小
- UVALive 3231 Fair Share 最大流(公平分配)
- rem详解及使用方法
- 如何实现超高并发的无锁缓存?
- CH340安卓驱动使用教程
- R语言Prod函数