ActiveMQ高可用集群的搭建

1        ActiveMQ集群的由来
单点的ActiveMQ作为企业应用无法满足业务的需求,因为单点的ActiveMQ存在单点故障问题,当该节点宕机以后,就会直接影响我们业务的正常运转,所以我们需要搭建高可用的ActiveMQ集群来支撑我们的业务系统
2        ActiveMQ集群的主要部署方式 2.1  默认的单机部署(kahadb
activeMQ的默认存储的单机方式,以本地kahadb文件的方式存储,所以性能指标完全依赖本地磁盘IO,不能提供高可用。
<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>
2.2  基于共享数据库的主从(Shared JDBC Master/Slave
可以基于 postgres mysql oracle 等常用数据库。每个节点启动都会争抢数据库锁,从而保证 master 的唯一性,其他节点作为备份,一直等待数据库锁的释放。因为所有消息读写,其实都是数据库操作, activeMQ 节点本身压力很小,性能完全取决于数据库性能。优点:实现高可用和数据安全 , 简单灵活, 2 台节点就可以实现高可用 缺点:稳定性依赖数据库 , 性能依赖数据库 .
<beanid="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>
2.3  基于zookeeper以及可复制的 LevelDB实现
5.9.0 新推出的主从实现,基于 zookeeper 来选举出一个 master ,其他节点自动作为 slave 实时同步消息。因为有实时同步数据的 slave 的存在, master 不用担心数据丢失,所以 leveldb 会优先采用内存存储消息,异步同步到磁盘。所以该方式的 activeMQ 读写性能都最好 ,特别是写性能能够媲美非持久化消息。优点:实现高可用和数据安全性能较好 . 缺点:因为选举机制要超过半数,所以最少需要 3 台节点 ,才能实现高可用。
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>
了解完毕 ActiveMQ 集群的三种部署方式以后 , 我们本教程将采用第三种方式来建 ActiveMQ 集群 , 因为第三种的读写性能都最好的 .
3        ActiveMQ高可用原理
使用 ZooKeeper (集群)注册所有的 ActiveMQ Broker 。只有其中的一个 Broker 可以提供服务,被视为  Master ,其他的  Broker  处于待机状态,被视为 Slave 。如果 Master 因故障而不能提供服务, Zookeeper 会从 Slave 中选举出一个 Broker 充当 Master Slave 连接 Master 并同步他们的存储状态, Slave 不接受客户端连接。所有的存储操作都将被复制到   连接至  Master Slaves 。如果 Master 宕了,得到了最新更新的 Slave 会成为  Master 。故障节点在恢复后会重新加入到集群中并连接 Master 进入 Slave 模式。
1        基于zookeeper以及leveldb实现高可用ActiveMQ集群
了解完毕 ActiveMQ 集群的三种部署方式以后 , 我们本教程将采用第三种方式来建 ActiveMQ 集群 , 因为第三种的读写性能都最好的 .
1.1  ActiveMQ集群部署规划
环境:   CentOS 6.6 x64    JDK7
版本:   ActiveMQ 5.11.1
zookeeper 集群说明 :  192.168.221.141:2181 , 192.168.221.141:2182, 192.168.221.141:2183
集群节点规划说明 :
  
主机
  
集群间通信端口
消息端口
管控台端口
其他端口
安装目录
192.168.221.136
62621
11616
8161
1 开始即可
  
/usr/local/src/activemq-cluster
192.168.221.136
62622
21616
8162
2 开始即可
192.168.221.136
62623
31616
8163
3 开始即可
1.2  搭建ActiveMQ步骤 1.2.1           准备环境
Ø  在/usr/local/src/在创建activemq-cluster目录: mkdir –p /usr/local/src/activemq-cluster
Ø  上传activemq安装包到linux服务器下
Ø  解压activemq的安装包: tar –zxvf –C /usr/local/src/activemq-cluster
Ø  重命名: mv apache-activemq-5.12.0/ activemq-cluster-node01
Ø  以1节点为基础复制两个节点出来
²  cp –r activemq-cluster-node01 activemq-cluster-node02
²  cp –r activemq-cluster-node01 activemq-cluster-node03
1.2.2           修改管理控制台端口可在 conf/jetty.xml 中修改
node01 管控台端口
  
<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>
  
node02 管控台端口
  
<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>
  
node03 管控台端口
  
<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>
  
1.2.3           配置持久化适配器
在 3 个 ActiveMQ 节点中配置  conf/activemq.xml 中的持久化适配器。修改其中 bind、zkAddress、hostname 和 zkPath. 注意 : 每个  ActiveMQ   BrokerName  必须相同,否则不能加入集群。
node01- 持久化适配器 :
  
<broker  xmlns="http://activemq.apache.org/schema/core" brokerName="activemq-cluster"  dataDirectory="${activemq.data}">
  
         <persistenceAdapter>
  
                   <replicatedLevelDB
  
                            directory="${activemq.data}/leveldb"
  
                            replicas="3"
  
                            bind="tcp://192.168.221.136:62621"
  
                            zkAddress="192.168.80.129:2182,192.168.80.129:2183,192.168.80.129:2184"
  
                            hostname="192.168.80.129"
  
                            zkPath="/activemq/leveldb-stores"
  
                   />
  
         </persistenceAdapter>
  
</broker>
  
node02- 持久化适配器 :
  
<broker xmlns="http://activemq.apache.org/schema/core"  brokerName="activemq-cluster"  dataDirectory="${activemq.data}">
  
         <persistenceAdapter>
  
                   <replicatedLevelDB
  
                            directory="${activemq.data}/leveldb"
  
                            replicas="3"
  
                            bind="tcp://192.168.221.136:62622"
  
                            zkAddress="192.168.221.145:2181,192.168.221.145:2182,192.168.221.145:2183"
  
                            hostname="192.168.221.136"
  
                            zkPath="/activemq/leveldb-stores"
  
                   />
  
         </persistenceAdapter>
  
</broker>
  
node03- 持久化适配器 :
  
<broker  xmlns="http://activemq.apache.org/schema/core" brokerName="activemq-cluster"  dataDirectory="${activemq.data}">
  
         <persistenceAdapter>
  
                   <replicatedLevelDB
  
                            directory="${activemq.data}/leveldb"
  
                            replicas="3"
  
                            bind="tcp://192.168.221.136:62623"
  
                            zkAddress="192.168.221.145:2181,192.168.221.145:2182,192.168.221.145:2183"
  
                            hostname="192.168.221.136"
  
                            zkPath="/activemq/leveldb-stores"
  
                   />
  
         </persistenceAdapter>
  
</broker>
  
1.2.4           修改消息服务端口
node-01 消息服务端口:
  
<transportConnectors>
  
            <transportConnector  name="openwire" uri="tcp://0.0.0.0:11616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
  
            <transportConnector  name="amqp" uri="amqp://0.0.0.0:1672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
  
            <transportConnector  name="stomp" uri="stomp://0.0.0.0:11613?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:11614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
  
</transportConnectors>
  
node-02 消息服务端口:
  
<transportConnectors>
  
            <transportConnector  name="openwire" uri="tcp://0.0.0.0:21616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
  
            <transportConnector  name="amqp" uri="amqp://0.0.0.0:2672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
  
            <transportConnector  name="stomp" uri="stomp://0.0.0.0:21613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
  
            <transportConnector  name="mqtt" uri="mqtt://0.0.0.0:2883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
  
            <transportConnector  name="ws" uri="ws://0.0.0.0:21614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
  
</transportConnectors>
  
node-03 消息服务端口:
  
<transportConnectors>
  
            <transportConnector  name="openwire" uri="tcp://0.0.0.0:31616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
  
            <transportConnector  name="amqp" uri="amqp://0.0.0.0:3672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
  
            <transportConnector  name="stomp" uri="stomp://0.0.0.0:31613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
  
            <transportConnector  name="mqtt" uri="mqtt://0.0.0.0:3883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
  
            <transportConnector  name="ws" uri="ws://0.0.0.0:31614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
  
</transportConnectors>
  
1.2.5           启动3ActiveMQ集群节点
  
/usr/local/src/activemq-cluster/apache-activemq-01/bin/activemq  start
  
/usr/local/src/activemq-cluster/apache-activemq-02/bin/activemq  start
  
/usr/local/src/activemq-cluster/apache-activemq-03/bin/activemq  start
  
监听日志
  
tail -f  /usr/local/src/activemq-cluster/apache-activemq-01/data/activemq.log
  
tail -f  /usr/local/src/activemq-cluster/apache-activemq-02/data/activemq.log
  
tail -f  /usr/local/src/activemq-cluster/apache-activemq-03/data/activemq.log
  
1.2.6           集群的节点状态分析
使用集群启动后对  ZooKeeper  数据的抓图,可以看到  ActiveMQ  的有  3  个节点,分别是  00000000019 000000000020  00000000021 。以下第一张图展现了  00000000019  的值,可以看到  elected  的值是不为空,说明这个节点是  Master ,其他两个节点是  Slave
1.1.1           集群测试
ActiveMQ 的客户端只能访问 MasterBroker, 其他处于 Slave Broker 不能访问 . 所以客户端连接 Broker 应该使用 failover( 故障转移 ) 协议
failover:(tcp://192.168.221.136:11616,tcp://192.168.221.136:21616,tcp:// 192.168.221.136:31616)?randomize=false
1.1.2           客户端连接url配置优化
updateURIsURL ,通过  URL (或者本地路径)获取重连的  url ,这样做具有良好的扩展性,因为客户端每次连接都是从  URL (或文件)中加载一次,所以可以随时从文件中更新  url  列表,做到动态添加  MQ  的备点。 failover:()?randomize=false&updateURIsURL=file:/home/wusc/activemq/urllist.txt,urllist.txt  中的地址通过英文逗号分隔,示例:
tcp://192.168.221.136:11616,tcp://192.168.221.136:21616,tcp:// 192.168.221.136:31616
1.1.3           集群测试结果说明
当一个 ActiveMQ 节点挂掉 , 或者一个 ZooKeeper 节点挂掉 ,ActiveMQ 服务依然正常运转 . 如果仅剩一个 ActiveMQ 节点 , 因为不能选举 Master,ActiveMQ 不能正常运转 ; 同样的 , 如果 ZooKeeper 仅剩一个节点活动 . 不管 ActiveMQ  各节点是否存活 ,ActiveMQ 也不能正常提供服务。 (ActiveMQ  集群的高可用,依赖于  ZooKeeper  集群的高可用)。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值