ActiveMQ高可用集群部署方案

简介: ActiveMQ是分布式系统中重要的组件,在生产环境中如何保证让ActiveMQ能够持续工作,同时还要使消息中间件服务保持可靠性和高效的处理性能。

1.概述

1.1简介

ActiveMQ是分布式系统中重要的组件,主要解决应用耦合、异步消息、流量削锋等问题,是大型分布式系统不可缺少的中间件。在生产环境中为了保证让ActiveMQ能够持续工作,我们还需要为消息中间件服务搭建集群环境,从而在保证消息中间件服务可靠性和处理性能。

1.2集群模式概述

集群模式主要是为了解决ActiveMQ系统架构中的两个关键问题:高可用和高性能。
针对上述两种需求,AActiveMQ主要有如下两种集群模式分别对应:

  • Master-slave模式
  • Broker-Cluster模式

1.2.1Master-slave模式

Master-Slave集群由至少3个节点组成,一个Master节点,其他为Slave节点。只有Master节点对外提供服务,Slave节点处于等待状态。当主节点宕机后,从节点会推举出一个节点出来成为新的Master节点,继续提供服务。
image
Master-Slave模式的部署方式,主要分为三种:

  • Shared Filesystem Master-Slave方式,如KahaDB,应用灵活、高效且安全。
  • Shared Database Master-Slave方式,基于共享数据库,跟第一种类似,性能会受限于数据库。
  • Replicated LevelDB Store方式,基于zookeeper + leveldb。是生产环境常用的方案。

1.2.2Broker-Cluster模式

Broker-Cluster部署方式中,各个broker通过网络互相连接,自动分发调用端请求,从而实现集群的负载均衡。Broker-Cluster集群连接到网络代理的方式,主要分为静态网络代理、动态网络代理,不同的网络代理方式也对应了不同的集群部署方式:

  • static Broker-Cluster
  • Dynamic Broker-Cluster
    在实际应用场景中static Broker-Cluster被大量使用。

image
静态网络代理示意图

1.3集群部署规划

1.3.1集群架构

Master-Slave集群的优点是可以解决多服务热备的高可用问题,但缺点是无法解决负载均衡和分布式的问题。Broker-Cluster集群的优点是可以解决负载均衡和分布式的问题,但不支持高可用。
因此,把Master-Slave和Broker-Cluster两者相结合,就可以得到一个完美的解决方案:即又可以做到集群负载均衡又可以做到任何一个broker如果发生宕机,也不会影响提供服务,节点消息也不会“丢失”。
在这里我们可以选择部署6个ActiveMQ实例,把6个ActiveMQ实例分成两组(Group)。Group1的三个节点通过Master-Slave模式组成brokerA,group2的3个节点通过Master-Slave模式组成brokerB,并使得brokerA与brokerB组成Broker-Cluster集群。
image

1.3.2服务器规划

一般情况下,生产环境需要多个ActiveMQ配置在多台服务器中,但是由于本次环境搭建仅用于学习测试,且本地环境的机器规格受限,所以接下来我们将会在两个docker容器中进行模拟,每个容器以3组端口运行3个ActiveMQ实例。因为是在一台机器上做实验,即使运行两个docker容器,也需要在宿主机映射对应的端口。所以不同的ActiveMQ实例需要有不同的端口配置,具体分配如下:

节点 IP openwire端口 admin端口
mq1 172.18.0.112 61616 8161
mq2 172.18.0.112 61617 8162
mq3 172.18.0.112 61618 8163
mq4 172.18.0.116 61619 8164
mq5 172.18.0.116 61620 8165
mq6 172.18.0.116 61621 8166

2.环境准备

2.1容器及网络环境准备

1.拉取centos7镜像

docker pull centos:7

2.创建自定义docker网络
默认情况下启动的Docker容器,都是使用bridge网络,容器重启时,docker的IP就会发生改变,且不支持为容器指定固定IP。
因此我们需要基于bridge创建自定义网络。

docker network create --subnet=172.18.0.0/16 qqnetwork

3.创建activemq所需容器

docker run -i -t --name mqbrokerAA -p 61616:61616 -p 61617:61617 -p 61618:61618 -p 8161:8161 -p 8162:8162 -p 8163:8163 --privileged=true --net qqnetwork --ip 172.18.0.112 -d centos:7

docker run -i -t --name mqbrokerBB -p 61619:61619 -p 61620:61620 -p 61621:61621 -p 8164:8164 -p 8165:8165 -p 8166:8166 --privileged=true --net qqnetwork --ip 172.18.0.116 -d centos:7

2.2Java环境

ActiveMQ运行前需要确保已经安装配置jdk8的环境,这部分资料有很多,这里不再赘述。

3.集群部署

3.1搭建Master-Slave集群

3.1.1安装ActiveMQ

1.在/usr/local目录下创建mqcluster目录,然后在该目录中创建mq1,mq2,mq3的文件夹。
image
2.将apache-activemq-5.15.3-bin.tar.gz压缩包的内容解压到这三个目录。

tar -zxvf apache-activemq-5.15.12-bin.tar.gz -C /usr/local/mqcluster/

3.分别单独运行3个ActiveMQ实例,保证单独运行正常。

3.1.2配置集群

3.1.2.1配置节点名

ActiveMQ Master-Slave集群的broker必须有统一的brokername,在这里需要修改ACTIVEMQ_HOME/conf/activemq.xml文件,将3个节点的brokerName统一为“brokerA”。

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="brokerA" dataDirectory="${activemq.data}">
3.1.2.2持久化配置

ActiveMQ的持久化主要有如下几种方案:

  • 基于日志文件存储,如KahaDB
  • JDBC消息存储,如使用mysql将消息持久化
  • LevelDB消息存储
    这里采用KahaDB的方式,原理就是让参与高可用的所有节点共用一个数据文件目录,通过文件锁的方式来决定谁是master谁是slave。在这里需要做的就是将3个节点的数据目录配置成相同的即可。

修改ACTIVEMQ_HOME/conf/activemq.xml文件,3个节点均修改成如下配置即可。

<persistenceAdapter>
     <kahaDB directory="/usr/local/mqcluster/mq1/data/kahadb"/>
</persistenceAdapter>
3.1.2.3TCP端口配置

实验环境暂时只用到tcp,所以只配置openwire,暂时将其它的端口配置注释掉。openwire默认为61616,同一个容器内端口不能重复,否则端口冲突,所以需要将mq1,mq2,mq3分别对应端口61616,61617,61618。
该配置也在ACTIVEMQ_HOME/conf/activemq.xml, 具体修改如下:

<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61617?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61618?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
3.1.2.4Jetty端口配置

ActiveMQ使用jetty运行服务,与openwire同理,3个节点运行的端口必须不同。修改ACTIVEMQ_HOME/conf/jetty.xml,3个节点依次改为8161,8162,8163。

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
        <!-- the default port number for the web console -->
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8161"/>
</bean>
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
        <!-- the default port number for the web console -->
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8162"/>
</bean>
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
        <!-- the default port number for the web console -->
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8163"/>
</bean>

3.1.3启动集群

至此,ActiveMQ高可用集群已经配置好了,然后分别启动mq1,mq2,mq3实例。

/usr/local/mqcluster/mq1/bin/activemq start
/usr/local/mqcluster/mq2/bin/activemq start
/usr/local/mqcluster/mq3/bin/activemq start

如果配置正常,在后启动的两个节点的启动日志中会输出如下日志,表示已经有master锁定,自己将以slave角色运行。

注意:只有master节点接受请求,slave不接受请求,也无法使用管理界面。

3.2搭建Broker-Cluster集群

3.2.1搭建第二组Master-Slave集群

上面我们已经搭建好了一个Master-Slave集群,但仅仅是master-slave的话只能保证高可用,却无法做到负载均衡,如果mq因负载过大挂掉, master-slave也无法解决这种问题,所以就必须配置Broker-Cluster模式实现ActiveMQ集群的负载均衡。
此时,可以按照上述方式及前期的集群规划依次安装配置mq4/mq5/mq6,即可完成另一个Master-Slave集群。

3.2.2配置Broker-Cluster集群

Broker-Cluster部署方式中,“静态方式”在实际应用场景中被大量使用,因此我们这里采用静态uri方式,具体操作如下所示。
1.在group1中所有的节点修改ACTIVEMQ_HOME/conf/activemq.xml文件,添加如下配置链接group2(在persistenceAdapter标签前配置):

<networkConnectors>
    <networkConnector name="brokerB" uri="static:(tcp://172.18.0.116:61619,tcp://172.18.0.116:61620,tcp://172.18.0.116:61621)" duplex="true" />
</networkConnectors>

需要注意,broker-cluster模式duplex默认为false,这种情况下broker-cluster可以实现消息分发,但消息只存在一个broker上。与此同时,也就意味着,一旦broker宕机,则可能会出现消息丢失。
这里我们配置duplex="true",当这个节点使用Network Bridge连接到其它目标节点后,将强制目标也建立Network Bridge进行反向连接。其目的在于让消息既能发送到目标节点,又可以通过目标节点接受消息。它相当于下面几行的效果:

<!-- 在group1中 -->  
<networkConnector name="group1-broker1" uri="static:(tcp://172.18.0.116:61619)" duplex="false" />  
<!-- 在group1中 -->  
<networkConnector name="group1-broker2" uri="static:(tcp://172.18.0.116:61620)" duplex="false" />  
<!-- 在group1中 -->  
<networkConnector name="group1-broker3" uri="static:(tcp://172.18.0.116:61621)" duplex="false" /> 
 
 
<!-- 在group2中 -->  
<networkConnector name="group2-broker1" uri="static:(tcp://172.18.0.112:61616)" duplex="false" />  
<!-- 在group2中 -->  
<networkConnector name="group2-broker2" uri="static:(tcp://172.18.0.112:61617)" duplex="false" />  
<!-- 在group2中 -->  
<networkConnector name="group2-broker3" uri="static:(tcp://172.18.0.112:61618)" duplex="false" />

2.上一步配置duplex="true"后,group2中所有的节点则不需要再修改ACTIVEMQ_HOME/conf/activemq.xml文件,也不需要再链接group1。

到这里,我们就已经完成了ActiveMQ高可用+负载均衡的集群搭建。在下一篇文章我们将结合Java工程,完成对本次搭建的ActiveMQ系统的功能验证、高可用及负载均衡功能验证。

相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
7月前
|
消息中间件 存储 缓存
一文读懂RocketMQ的高可用机制——集群管理高可用
一文读懂RocketMQ的高可用机制——集群管理高可用
1227 1
|
8月前
|
消息中间件 运维 网络协议
rabbitmq 高可用集群部署踩坑
rabbitmq 高可用集群部署踩坑
224 0
|
9月前
|
消息中间件 存储 负载均衡
中间件优解——RabbitMQ和Kafka的高可用集群原理
大家对当前比较常用的RabbitMQ和Kafka是否有一些了解呢,了解的多一些也不是坏事,面试或者跟人聊技术的时候也会让你更有话语权嘛。 今天就跟大家聊一聊RabbitMQ和Kafka在处理高可用集群时的原理,看看它们与RocketMQ有什么不同。小伙伴们可以重新温习一下常见的消息中间件有哪些?你们是怎么进行技术选型的?这篇文章,了解一下他们之间的区别。
|
10月前
|
消息中间件 存储 算法
解读 RocketMQ 5.0 全新的高可用设计
本文主要介绍高可用架构的演进以及RocketMQ 5.0 全新的高可用设计。
11744 22
|
11月前
|
消息中间件 Linux Docker
RabbitMQ单机部署和集群部署
RabbitMQ单机部署和集群部署
130 0
|
消息中间件 存储 JSON
RocketMQ的单机部署
RocketMQ的单机部署
361 0
RocketMQ的单机部署
|
消息中间件 网络安全
RabbitMQ多机多节点集群部署(下)
RabbitMQ多机多节点集群部署
223 0
|
消息中间件 网络安全 数据安全/隐私保护
RabbitMQ多机多节点集群部署(上)
RabbitMQ多机多节点集群部署
236 0
|
消息中间件 存储 监控
如何零宕机将 2000 个微服务从本地 Kafka 集群迁移至云托管多集群平台?
2021 年,我们的团队致力于将 Wix (国外比较火的一款建站平台)的 2000 个微服务从自托管的 Kafka 集群迁移到多集群的 Confluent Cloud 平台( Confluent Enterprise 的云端托管服务),整个过程是无缝的方式,无需服务所有者参与,且迁移是在正常通信中进行,没有任何停机。
233 0
如何零宕机将 2000 个微服务从本地 Kafka 集群迁移至云托管多集群平台?
|
消息中间件 负载均衡 监控
RabbitMQ 集群高可用原理及实战部署介绍(四)
在项目中想要 RabbitMQ 变得更加健壮,就要使得其变成高可用,今天我们一起来聊聊关于 RabbitMQ 集群原理和部署流程
RabbitMQ 集群高可用原理及实战部署介绍(四)