【系统运维】Centos部署Haproxy+Keepalived+RabbitMQ高可用集群

1.RabbitMQ高可用集群方案

(1)RabbitMQ搭建集群的作用:提高可用性、可靠性和处理能力,确保系统提供高效的消息传递服务

  • 高可用性:通过集群,即使其中一个节点发生故障,其他节点仍然可以继续提供服务,确保消息的可靠传递。
  • 负载均衡:集群可以将消息负载均匀地分布到多个节点上,提高系统的处理能力,同时避免单个节点过载。
  • 故障恢复:如果集群中的一个节点发生故障,可以通过故障检测和自动恢复机制,将该节点从集群中移除,并将其负载重新分配给其他节点,保证整个系统的连续性和可用性。
  • 扩展性:当消息的产生量和消费量逐渐增加时,可以向集群中添加更多的节点来扩展系统的处理能力,以应对不断增长的负载。

(2)常见的集群方案

  • RabbitMQ普通集群
    • 默认的集群模式, 比如有节点 node1和node2 两个节点是普通集群,但他们仅有相同的元数据,即交换机、队列的结构;
    • 消息只存在其中的一个节点里面,假如消息A,存储在node1节点,消费者连接node1个节点消费消息时,可以直接取出来;
    • 但如果 费者是连接的是其他节点 那rabbitmq会把 queue 中的消息从存储它的节点中取出,并经过连接节点转发后再发送给消费者;
    • 假如node1故障,那node2无法获取node1存储未被消费的消息;
    • 如果node1持久化后故障,那需要等node1恢复后才可以正常消费,如果ndoe1没做持久化后故障,那消息将会丢失;
    • 这个情况无法实现高可用性,且节点间会增加通讯获取消息,性能存在瓶颈;
    • 该模式更适合于消息无需持久化的场景,如日志传输的队列;
  • RabbitMQ镜像集群
    • 队列做成镜像队列,让各队列存在于多个节点中;
    • 和普通集群比较大的区别就是【队列queue的消息message 】会在集群各节点之间同步;
    • 且并不是在 consumer 获取数据时临时拉取,而普通集群则是临时从存储的节点里面拉取对应的数据;
    • 实现了高可用性,部分节点挂掉后,不影响正常的消费;
    • 可以保证100%消息不丢失,推荐3个奇数节点,结合LVS+Keepalive 或 Haproxy进行IP漂移,防止单点故障;
    • 由于镜像队列模式下,消息数量过多,大量的消息同步也会加大网络带宽开销;
    • 适合高可用要求比较高的项目 过多节点的话,性能则更加受影响;

2.RabbitMQ高可用集群架构

在这里插入图片描述

将两个 RabbitMQ 磁盘节点和一个 RabbitMQ内存节点组成一个内建集群,之所以要用两个磁盘节点是防止,唯一的磁盘节点挂掉后,不能重建队列,交换机。用 HAProxy 作为 RabbitMQ 集群的负载均衡。为了防止 HAProxy 单点故障,用 Keepalived 将两个 HAProxy 节点做成一主一备。应用使用 VIP(虚拟IP) 访问 HAProxy 服务时,默认连接主机(Master)的 HAProxy,当主机(Master)上的 HAProxy 故障时,VIP 会漂移到备机(Backup)上,就会连接备机(Backup)上的 HAProxy 服务。

VRRP 协议
VRRP 协议即虚拟路由冗余协议(Virtual Router Redundancy Protocol)。Keepalived 中提供的虚拟 IP 机制就属于 VRRP,它是为了避免路由器出现单点故障的一种容错协议。

3.RabbitMQ高可用集群搭建

(1)机器准备

IP地址主机名备注
192.168.140.101mq01磁盘节点 RabbitMQ
192.168.140.102mq02内存节点 keepalived+haproxy+RabbitMQ
192.168.140.103mq03内存节点 keepalived+haproxy+RabbitMQ

(2)三台机器docker部署RabbitMQ

参数说明:

--hostname:自定义Docker容器的hostname
--privileged=true:使用该参数,container内的root拥有真正的root权限,否则容器出现permission denied
-v:宿主机和容器路径映射
RABBITMQ_ERLANG_COOKIE:Erlang Cookie 值,同一个集群内该值必须相同,相当于不同节点之间通讯的密钥
--add-host:修改容器内部的hosts,添加的集群服务器都需要添加进来
--restart=unless-stopped docker 容器重启后重启MQ
  • 节点一
docker run  -d --hostname rabbitmq1 --add-host=rabbitmq2:192.168.140.102 --add-host=rabbitmq3:192.168.140.103 --restart=unless-stopped --name rabbitmq1 --net host -p 15672:15672  -p 5672:5672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -e RABBITMQ_ERLANG_COOKIE='rabbit_mq'  rabbitmq:management
  • 节点二
docker run  -d --hostname rabbitmq2 --add-host=rabbitmq1:192.168.140.101 --add-host=rabbitmq3:192.168.140.103 --restart=unless-stopped --name rabbitmq2 --net host -p 15672:15672  -p 5672:5672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -e RABBITMQ_ERLANG_COOKIE='rabbit_mq'  rabbitmq:management
  • 节点三
docker run  -d --hostname rabbitmq3 --add-host=rabbitmq1:192.168.140.101 --add-host=rabbitmq2:192.168.140.102 --restart=unless-stopped --name rabbitmq3 --net host -p 15672:15672  -p 5672:5672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -e RABBITMQ_ERLANG_COOKIE='rabbit_mq'  rabbitmq:management
  • 节点一配置集群。
docker exec -it rabbitmq1 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
exit
  • 节点二加入集群,–ram是以内存方式加入,忽略该参数默认为磁盘节点。
docker exec -it rabbitmq2 bash
rabbitmqctl stop_app
rabbitmqctl join_cluster --ram rabbit@rabbitmq1
rabbitmqctl start_app
exit
  • 节点三加入集群,–ram是以内存方式加入,忽略该参数默认为磁盘节点。
docker exec -it rabbitmq3 bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@rabbitmq1
rabbitmqctl start_app
exit

在这里插入图片描述

  • 查看集群节点状态,配置启动了3个节点,1个磁盘节点和2个内存节点。
rabbitmqctl cluster_status
  • 内存节点(ram):将元数据都放在内存里,内存节点的话,只要服务重启,该节点的所有数据将会丢失。
  • 硬盘节点(disc):将元数据都放在硬盘里,所以服务重启的话,数据也还是会存在的。

在这里插入图片描述

(3)搭建镜像集群

  • 前面搭建了普通集群,如果磁盘节点挂掉后,如果没开启持久化数据就丢失了,其他节点也无法获取消息。
  • 所以我们这个集群方案需要进一步改造为镜像模式集群
  • rabbitmq的策略policy是用来控制和修改集群的vhost,队列和Exchange复制行为,就是要设置哪些Exchange或者queue的数据需要复制、同步,以及如何复制同步。

配置步骤:rabbitmq管理页面 —> Admin —> Policies —> Add / update a policy

在这里插入图片描述

策略会同步同一个VirtualHost中的交换器和队列数据

  • name:自定义策略名称
  • Pattern:^ 匹配符,代表匹配所有
  • Definition:ha-mode=all 为匹配类型,分为3种模式:all(表示所有的queue)
  • ha-mode: 指明镜像队列的模式,可选下面的其中一个
    • all:表示在集群中所有的节点上进行镜像同步(一般都用这个参数)
    • exactly:表示在指定个数的节点上进行镜像同步,节点的个数由ha-params指定
    • nodes:表示在指定的节点上进行镜像同步,节点名称通过ha-params指定
    • ha-sync-mode:镜像消息同步方式 automatic(自动),manually(手动)

在这里插入图片描述
在这里插入图片描述

策略会同步同一个VirtualHost中的交换器和队列数据,在MQ节点一上创建队列,同步到各个节点。

在这里插入图片描述

集群重启顺序:

  • 集群重启的顺序是固定的,并且是相反的
  • 启动顺序:磁盘节点 => 内存节点
  • 关闭顺序:内存节点 => 磁盘节点
  • 最后关闭必须是磁盘节点,否则容易造成集群启动失败、数据丢失等异常情况

4.Haproxy高可用集群搭建

(1)MQ集群的架构痛点

  • 搭建了RabbitMQ高可用集群,生产者和消费者,业务代码里面需要写多个节点配置信息。

  • 如果某个节点挂了,或者新增了多个节点,多个业务程序都需要重启更新配置信息。

  • 可以利用Haproxy在RabbitMQ中充当负载均衡器的角色,提供负载均衡、故障转移、可靠性和可用性增强以及动态伸缩等功能。

在这里插入图片描述

(2)创建配置文件

分别在102和103节点上创建目录/usr/local/haproxy

创建配置文件haproxy.cfg

#增加下面配置文件
global
  log 127.0.0.1 local0 info
  maxconn 10240
  daemon
  
defaults
  log global
  mode http
  timeout connect 3000 
  timeout client 3000
  timeout server 3000
  timeout check 2000

listen  admin_stats
    #haproxy监控界面的访问的IP和端口    
    bind  0.0.0.0:8081
    mode        http
    stats uri   /stats
    stats realm     Global\ statistics
    #haproxy登陆帐户信息
    stats auth  admin:admin

listen rabbitmq_admin
    #rabbit的监控页面
    bind    0.0.0.0:8082
    server  rabbit_admin1 192.168.140.101:15672
    server  rabbit_admin2 192.168.140.102:15672
    server  rabbit_admin3 192.168.140.103:15672

listen haproxy
  #对外提供的端口,spring boot连接mq的端口
  bind 0.0.0.0:8091
  option tcplog
  mode tcp
  balance roundrobin
  server rabbitmq1 192.168.140.101:5672 check inter 5000 rise 2 fall 2
  server rabbitmq2 192.168.140.102:5672 check inter 5000 rise 2 fall 2
  server rabbitmq3 192.168.140.103:5672 check inter 5000 rise 2 fall 2

配置文件详解

全局配置部分(global):
  - 设置日志输出目标为本地地址 `127.0.0.1``local0` 日志设备,并设置日志级别为 `info`。
  - 设置最大连接数为 `10240`。
  - 启用后台运行模式。
默认配置部分(defaults):
  - 设置日志输出为全局设定的日志设备。
  - 指定工作模式为HTTP模式。
  - 设置连接超时时间为 `3000` 毫秒。
  - 设置客户端超时时间为 `3000` 毫秒。
  - 设置服务器超时时间为 `3000` 毫秒。
  - 设置健康检查超时时间为 `2000` 毫秒。
`admin_stats` 监听器:
  - 监听 `0.0.0.0:8081` 地址和端口。
  - 使用HTTP模式。
  - 设置监控统计信息的路径为 `/stats`。
  - 设置统计信息页面的显示名称为 `Global statistics`。
  - 设置访问统计信息页面的认证用户名和密码为 `admin:xdclass.net168``rabbitmq_admin` 监听器:
  - 监听 `0.0.0.0:8082` 地址和端口。
  - 配置了三个RabbitMQ管理节点。
  - 每个节点的名称和地址:端口为 `rabbit_admin1 120.24.7.58:15672``rabbit_admin2 120.24.7.58:15673``rabbit_admin3 120.24.7.58:15674``haproxy` 监听器:
  - 监听 `0.0.0.0:5666` 地址和端口。
  - 启用TCP日志记录。
  - 使用TCP模式。
  - 使用轮询算法进行负载均衡。
  - 配置了三个RabbitMQ节点。
  - 每个节点的名称和地址:端口为 `rabbitmq1 120.24.7.58:5672``rabbitmq2 120.24.7.58:5673``rabbitmq3 120.24.7.58:5674`。
  - 设置了健康检查的参数:每5000毫秒检查一次,如果连续2次检查成功就认为节点上线,如果连续2次检查失败则认为节点宕机。

两台机器分别启动haproxy

docker run -d -i --name haproxy-rabbitmq -p 8081:8081 -p 8091:8091 -p 8082:8082 -v /usr/local/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg --privileged=true -u root  haproxy:latest 

访问路径

  • Haproxy: http://192.168.140.103:8081/stats,http://192.168.140.102:8081/stats
  • RabbitMQ管控台:http://192.168.140.102:8082,http://192.168.140.103:8082

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

5.Keepalived高可用集群搭建

(1)102和103节点分别下载Keepalived

#yum安装
yum -y install keepalived

(2)编辑配置文件

! Configuration File for keepalived
global_defs {
   router_id LVS_DEVEL # 设置lvs的id,在一个网络内应该是唯一的
   enable_script_security #允许执行外部脚本
}
#配置vrrp_script,主要用于健康检查及检查失败后执行的动作。
vrrp_script chk_real_server {
    weight -5
    fall 3
    rise 2
    user root
}
vrrp_instance VI_1 {
		#配置节点是master还是backup,102配置MASTER,103配置BACKUP
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    #配置虚拟IP
    virtual_ipaddress {
        192.168.140.100
    }
}
virtual_server 192.168.140.100 8082 {
    # 设置健康检查时间,单位是秒
    delay_loop 6
    # 设置负载调度的算法为rr
    lb_algo rr
    # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式
    lb_kind NAT
    # 会话保持时间
    persistence_timeout 50
   #指定转发协议类型(TCP、UDP)
    protocol TCP
    # 指定real server1的IP地址
    real_server 192.168.140.102 8082 {
        weight 1
    }
    real_server 192.168.140.103 8082 {
        weight 1
    }
}

(3)启动keepalived,访问MQ集群

systemctl start keepalived.service

在这里插入图片描述

Ok,发现已经成功的通过keepalived访问mq节点。

当我们把102主节点的keepalived停掉时,虚拟IP会漂移到103的节点上。

在这里插入图片描述

OK,至此RabbitMQ高可用集群就已经搭建完成了。

记得给博主三连哦!!!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/213714.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ 学习笔记——C++纯虚函数和抽象类

C纯虚函数 什么是纯虚函数 1,纯虚函数只有函数名、参数、返回值类型。 2,纯虚函数的定义是在函数句首使用 virtual 关键字修饰,并且在句末增加 “ 0”。 virtual void funtion() 0;3,纯虚函数只有声明,基类可以存…

LLM 开发模式 RAG,MRKL,Re-Act,Plan-Execute 模式对比

本心、输入输出、结果 文章目录 LLM 开发模式 RAG,MRKL,Re-Act,Plan-Execute 模式对比前言RAG、MRKL、Re-Act和Plan-Execute模式的一些对比花有重开日,人无再少年实践是检验真理的唯一标准 LLM 开发模式 RAG,MRKL&…

JVM:强软弱虚四种引用

下面依次解释五种引用 一、强引用 把一个对象赋值给一个引用变量,就相当于把这个对象的强引用放到变量中。 只要对象可达, GC一定不会回收这个对象(A1) 二、软引用 当一个对象(A2)没有强引用时&#xff…

图文并茂教你模拟302接口,实现js中axios,fetch遇到302状态码后跳转的多种方案axios,fetch成功响应拦截302

前情提要 日常工作中,我们会使用fetch,或者axios发起请求来获取数据,但是当我们遇到一些特殊需求的时候,使用不同库之后,会得到不同的结果,例如302,308的状态码,那么我们应该怎么处理这两种情况呢&#xf…

C语言练习题

C语言练习题 文章目录 C语言练习题题目一题目二题目三题目四题目五题目六题目八 题目一 #include <stdio.h> //VS2022,默认对齐数为8字节 union Un {short s[7];int n; };int main() {printf("%zd", sizeof(union Un));return 0; }代码运行结果:> 16 sizeo…

Springboot依赖注入时重复初始化Bean的问题

前言 最近做项目&#xff0c;发现了springboot2.7.x在参数initiate的时候可以反复初始化&#xff0c;而且首次异常后&#xff0c;第二次成功居然也可以启动&#xff0c;通过查看源代码发现了问题根源&#xff0c;且在springboot高版本3.x&#xff0c;就出现了了Configuration的…

pytorch 中的dim 的作用范围

1. 二维矩阵时 不同的运算&#xff0c; dim 的作用域都是一样的思想&#xff1b; 当数据是二维矩阵时&#xff0c; 可以按照下面的思想理解&#xff1a; 对于矩阵&#xff1a; dim0 按列操作&#xff08;沿列向下&#xff09;。 dim1 按行操作&#xff08;跨行&#xff09;。 …

JavaSE学习路线及经验所谈

前言 一.学习框架二.学习经验 相信很多小白刚开始学习Java时&#xff0c;都是靠自己在网上搜集资料&#xff0c;并没有明确规划&#xff0c;不知道要学习什么内容&#xff0c;也不知道学习的重点是什么&#xff0c;那么这篇文章会给你一个大致的指引&#xff0c;当然也可以作为…

【力扣】——可获得的最大点数(滑动窗口)

几张卡牌 排成一行&#xff0c;每张卡牌都有一个对应的点数。点数由整数数组 cardPoints 给出。 每次行动&#xff0c;你可以从行的开头或者末尾拿一张卡牌&#xff0c;最终你必须正好拿 k 张卡牌。 你的点数就是你拿到手中的所有卡牌的点数之和。 给你一个整数数组 cardPoi…

深度学习 第3章 Python程序设计语言(3.2 Python程序流程控制)

无论是在机器学习还是深度学习中&#xff0c;Python已经成为主导性的编程语言。而且&#xff0c;现在许多主流的深度学习框架&#xff0c;例如PyTorch、TensorFlow也都是基于Python。本课程主要是围绕“理论实战”同时进行&#xff0c;所以本章将重点介绍深度学习中Python的必备…

探秘Python FastAPI、Sanic、Tornado 与Golang Gin性能之战!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Python和Golang作为两种流行的编程语言&#xff0c;都拥有强大的异步框架&#xff0c;为开发者提供了在构建高性能应用时的选择。在Python阵营中&#xff0c;FastAPI、Sanic、Tornado等框架因其异步特性和高效的…

React18 入门与进阶

React18 入门与进阶 前言一、核心概念与类组件使用1、虚拟DOM与新的渲染写法2、JSX 与 JSX 的使用3、类组件和函数组件4、类组件与类组件通信5、props详解与注意事项6、类组件中事件的使用7、类组件响应式数据实现与原理8、PureComponent 与 shouldComponentUpdate9、immutable…

数据结构之堆排序以及Top-k问题详细解析

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 数据结构初阶 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力 目录 1.前言 2.堆排序 2.1降序排序 2.2时间复杂…

领域驱动架构(DDD)建模

一、背景 常见的软件开发方式是拿到产品需求后&#xff0c;直接考虑数据库中表应该如何设计&#xff0c;这种方式已经将设计与业务需求脱节&#xff0c;而更多的是直接考虑应该如何实现了&#xff0c;这有点本末倒置。而DDD是从领域(问题域)为出发点进行的设计方法。 领域驱动…

JSP格式化标签 parseDate将指定时间格式字符串转为真正的date对象

格式化标签最后一个就是 parseDate 作用 将一个日期/时间格式字符串 转为 真正的date时间类型 有点无语 这种 东西应该都是在java中去做的 而不是在java中 这个建议也是做个了解即可 作用不是那么大 基本语法如下 这里 我们 直接编写代码如下 <% page contentType"…

【Linux服务器Java环境搭建】附录01:判断Linux服务器是X64还是arm架构的方式

【Linux服务器Java环境搭建】01购买云服务器以及在服务器中安装Linux系统 【Linux服务器Java环境搭建】02 通过xftp和xshell远程连接云服务器 【Linux服务器Java环境搭建】03 Git工具安装 【Linux服务器Java环境搭建】04 JDK安装&#xff08;JAVA环境安装&#xff09; 【Linux服…

测试基础知识

常见测试分类 按测试阶段划分&#xff1a; 单元测试&#xff1a;针对程序源码进行测试。&#xff08;国内是开发自测&#xff09;集成测试&#xff1a;又称接口测试&#xff0c;针对模块间的访问地址进行测试。系统测试&#xff1a;对整个系统进行测试&#xff0c;包括功能、兼…

手写实现一个动态代理框架

手写实现一个动态代理框架 什么是代理模式什么是动态代理动态代理中的编译、类加载与对象实例化手写实现一个动态代理框架实现细节DynamicProxyHandlerProxy生成代码写入代码到磁盘文件调用编译器进行编译调用类加载器进行类加载反射实例化删除前面生成的java文件和class文件 C…

基于springboot实现智能停车场管理平台

一、系统架构 前端&#xff1a;vue | echarts | html | layui 后端&#xff1a;springboot | mybatis-plus 环境&#xff1a;jdk1.8 | mysql | maven 二、代码及数据库 三、功能介绍 01. 登录页 02. 控制台 03. 停车场管理-停车场管理 04. 停车场管理-停车场区…

leetcode 15. 三数之和(优质解法)

代码&#xff1a; class Solution {public static List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);List<List<Integer>> listsnew ArrayList<>();int lengthnums.length;for(int i0;i<length-3;){int lefti1;int rightlength…
最新文章