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系统的功能验证、高可用及负载均衡功能验证。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
消息中间件 运维 监控
深入解析Kafka中Replica的妙用
深入解析Kafka中Replica的妙用
809 0
|
消息中间件 存储 监控
ActiveMQ系列: ActiveMQ 的死信队列与消费重试机制
maximumRedeliveryDelay:最大传送延迟,只在 useExponentialBackOff 为 true 时有效(V5.5),假设首次重连间隔为 10ms,倍数为 2,那么第二次重连时间间隔为 20ms,第三次重连时间间隔为 40ms,当重连时间间隔大的最大重连时间间隔时,以后每次重连时间间隔都为最大重连时间间隔。默认为 -1。
1586 0
ActiveMQ系列: ActiveMQ 的死信队列与消费重试机制
|
消息中间件 存储 运维
2024最全RabbitMQ集群方案汇总
本文梳理了RabbitMQ集群的几种方案,主要包括普通集群、镜像集群(高可用)、Quorum队列(仲裁队列)、Streams集群模式(高可用+负载均衡)和插件方式。重点介绍了每种方案的特点、优缺点及适用场景。搭建步骤包括安装Erlang和RabbitMQ、配置集群节点、修改hosts文件、配置Erlang Cookie、启动独立节点并创建集群,以及配置镜像队列以提高可用性和容错性。推荐使用Quorum队列与Streams模式,其中Quorum队列适合高可用集群,Streams模式则同时支持高可用和负载均衡。此外,还有Shovel和Federation插件可用于特定场景下的集群搭建。
3245 2
|
运维 Kubernetes 数据安全/隐私保护
K8S 拉取私有仓库镜像
在Kubernetes中从私有仓库拉取镜像时,需先创建包含认证信息的Secret,然后在Pod或Deployment中引用此Secret。本文通过具体步骤演示了如何创建Secret、更新Kubernetes资源配置文件以引用Secret,并验证了镜像拉取及应用运行的成功。
1213 6
|
监控 负载均衡 网络协议
一文带你浅入浅出Keepalived
一文带你浅入浅出Keepalived
10546 117
|
消息中间件 存储 缓存
消息中间件ActiveMQ常见问题解析
消息中间件ActiveMQ常见问题解析
651 90
|
消息中间件 存储 NoSQL
ActiveMQ系列:基于LevelDB和 Zookeeper 的数据复制集群
LeveDB 5.6版本之后推出了 LevelDB 的持久化引擎,它使用了自定义的索引代替常用的 BTree 索引,其持久化性能高于KahaDB,虽然默认的持久化方式还是 KahaDB,但是 LevelDB 可能会是趋势。在5.9版本还提供了基于 LevelDB 和 Zookeeper 的数据复制方式,作为 Master-Slave 方式的首选数据复制方案。
510 0
ActiveMQ系列:基于LevelDB和 Zookeeper 的数据复制集群
|
消息中间件 Java 数据安全/隐私保护
企业实战(12)消息队列之Docker安装部署ActiveMQ实战
企业实战(12)消息队列之Docker安装部署ActiveMQ实战
626 0
|
消息中间件 存储 负载均衡
『RabbitMQ』手把手带你搭建RabbitMQ镜像集群
📣读完这篇文章里你能收获到 - RabbitMQ多种模式的区别及概念 - 手把手带你搭建高可用集群 - 接入HaProxy做高可用负载均衡 - 针对生产突发的异常场景提进行测试验证
4695 0
『RabbitMQ』手把手带你搭建RabbitMQ镜像集群
|
网络协议 安全 前端开发
27-微服务技术栈(高级):分布式事务Seata集群部署与服务整合
在分布式架构系统中,服务不止一个,一个完整的业务链路肯定也不止调用一个服务,此时每个服务都有自己的数据库增删改查,而每一个写操作对应一个本地事务。如果想要确保全部的业务状态一致,也就意味着需要所有的本地事务状态一致,这在我们之前的学习中肯定是不具备的,如何做到跨服务、跨数据源的事务一致性将是本章节的重点学习内容。
1022 0

热门文章

最新文章