RabbitMQ——基于 KeepAlived + HAProxy 搭建 RabbitMQ 高可用负载均衡集群

news2024/11/27 11:48:55

一、集群简介

1.1 集

群架构

当单台 RabbitMQ 服务器的处理消息的能力达到瓶颈时,此时可以通过 RabbitMQ 集群来进行扩展,从而达到提升吞吐量的目的。

RabbitMQ 集群是一个或多个节点的逻辑分组,集群中的每个节点都是对等的,每个节点共享所有的用户,虚拟主机,队列,交换器,绑定关系,运行时参数和其他分布式状态等信息。一个高可用,负载均衡的 RabbitMQ 集群架构应类似下图: 

这里对上面的集群架构做一下解释说明:

首先,一个基本的 RabbitMQ 集群不是高可用的,虽然集群共享队列,但在默认情况下,消息只会被路由到某一个节点的符合条件的队列上,并不会同步到其他节点的相同队列上。假设消息路由到 node1 的 my-queue 队列上,但是 node1 突然宕机了,那么消息就会丢失,想要解决这个问题,需要开启队列镜像,将集群中的队列彼此之间进行镜像,此时消息就会被拷贝到处于同一个镜像分组中的所有队列上。

其次 ,RabbitMQ 集群本身并没有提供负载均衡的功能,也就是说对于一个三节点的集群,每个节点的负载可能都是不相同的,想要解决这个问题可以通过硬件负载均衡或者软件负载均衡的方式,这里我们选择使用 HAProxy 来进行负载均衡,当然也可以使用其他负载均衡中间件,如 LVS 等。HAProxy 同时支持四层和七层负载均衡,并基于单一进程的事件驱动模型,因此它可以支持非常高的井发连接数。

接着,假设我们只采用一台 HAProxy ,那么它就存在明显的单点故障的问题,所以至少需要两台 HAProxy ,同时这两台 HAProxy 之间需要能够自动进行故障转移,通常的解决方案就是 KeepAlived 。KeepAlived 采用 VRRP (Virtual Router Redundancy Protocol,虚拟路由冗余协议) 来解决单点失效的问题,它通常由一组一备两个节点组成,同一时间内只有主节点会提供对外服务,并同时提供一个虚拟的 IP 地址(Virtual Internet Protocol Address ,简称 VIP) 。 如果主节点故障,那么备份节点会自动接管 VIP 并成为新的主节点 ,直到原有的主节点恢复。

最后,任何想要连接到 RabbitMQ 集群的客户端只需要连接到虚拟 IP,而不必关心集群是何种架构,示例如下:

ConnectionFactory factory = new ConnectionFactory();
// 假设虚拟ip为 192.168.0.200
factory.setHost("192.168.0.200");

1.2 部署情况

下面我们开始进行搭建,这里我使用三台主机进行演示,主机名分别为 rabbit-1,2 和 3 ,其功能分配如下:

  • rabbit-1 服务器:部署 RabbitMQ + HAProxy + KeepAlived ;

  • rabbit-2 服务器:部署 RabbitMQ + HAProxy + KeepAlived ;

  • rabbit-3 服务器:部署 RabbitMQ

二、HAProxy 环境搭建

2.1 下载

HAProxy 官方下载地址为:www.haproxy.org/#down ,如果这个网站无法访问,也可以从 src.fedoraproject.org/repo/pkgs/h… 上进行下载。

这里我下载的是 2.x 的版本,下载后进行解压:

tar -zxvf haproxy-2.0.3.tar.gz

2.2 编译

进入解压后根目录,执行下面的编译命令:

make TARGET=linux-glibc  PREFIX=/usr/app/haproxy-2.0.3
make install PREFIX=/usr/app/haproxy-2.0.3

2.3 配置环境变量

配置环境变量:

vim /etc/profile
export HAPROXY_HOME=/usr/app/haproxy-2.0.3
export PATH=$PATH:$HAPROXY_HOME/sbin

2.4 负载均衡配置

# 全局配置
global
    # 日志输出配置、所有日志都记录在本机,通过 local0 进行输出
    log 127.0.0.1 local0 info
    # 最大连接数
    maxconn 4096
    # 改变当前的工作目录
    chroot /usr/app/haproxy-2.0.3
    # 以指定的 UID 运行 haproxy 进程
    uid 99
    # 以指定的 GID 运行 haproxy 进程
    gid 99
    # 以守护进行的方式运行
    daemon
    # 当前进程的 pid 文件存放位置
    pidfile /usr/app/haproxy-2.0.3/haproxy.pid

# 默认配置
defaults
    # 应用全局的日志配置
    log global
    # 使用4层代理模式,7层代理模式则为"http"
    mode tcp
    # 日志类别
    option tcplog
    # 不记录健康检查的日志信息
    option dontlognull
    # 3次失败则认为服务不可用
    retries 3
    # 每个进程可用的最大连接数
    maxconn 2000
    # 连接超时
    timeout connect 5s
    # 客户端超时
    timeout client 120s
    # 服务端超时
    timeout server 120s

# 绑定配置
listen rabbitmq_admin
    bind :15673
    mode tcp
    balance roundrobin
    server node1 rabbit-1:15672
    server node2 rabbit-2:15672
    server node3 rabbit-3:15672

# 绑定配置
listen rabbitmq_cluster
    bind :5673
    # 配置TCP模式
    mode tcp
    # 采用加权轮询的机制进行负载均衡
    balance roundrobin
    # RabbitMQ 集群节点配置
    server node1 rabbit-1:5672 check inter 5000 rise 2 fall 3 weight 1
    server node2 rabbit-2:5672 check inter 5000 rise 2 fall 3 weight 1
    server node3 rabbit-3:5672 check inter 5000 rise 2 fall 3 weight 1

# 配置监控页面
listen monitor
    bind :8100
    mode http
    option httplog
    stats enable
    stats uri /stats
    stats refresh 5s

负载均衡的主要配置在 listen rabbitmq_cluster 下,这里指定负载均衡的方式为加权轮询,同时定义好健康检查机制:

server node1 rabbit-1:5672 check inter 5000 rise 2 fall 3 weight 1

以上配置代表对地址为 rabbit-1:5672 的 node1 节点每隔 5 秒进行一次健康检查,如果连续两次的检查结果都是正常,则认为该节点可用,此时可以将客户端的请求轮询到该节点上;如果连续 3 次的检查结果都不正常,则认为该节点不可用。weight 用于指定节点在轮询过程中的权重。

2.5 启动服务

以上搭建步骤在 rabbit-1 和 rabbit-2 上完全相同,搭建完成使用以下命令启动服务:

haproxy -f /etc/haproxy/haproxy.cfg

启动后可以在监控页面进行查看,端口为设置的 8100,完整地址为:http://rabbit-1:8100/stats ,页面情况如下:

所有节点都为绿色,代表节点健康。此时证明 HAProxy 搭建成功,并已经对 RabbitMQ 集群进行监控。 

三、KeepAlived 环境搭建

接着就可以搭建 Keepalived 来解决 HAProxy 故障转移的问题。这里我在 rabbit-1 和 rabbit-2 上安装 KeepAlived ,两台主机上的搭建的步骤完全相同,只是部分配置略有不同。

3.1 下载

直接从 Keepalived 官方下载所需版本,这里我下载的为 2.x 的版本。下载后进行解压:

wget https://www.keepalived.org/software/keepalived-2.2.2.tar.gz

3.2 编译

安装相关依赖后进行编译:

# 安装依赖
yum -y install libnl libnl-devel
yum install gcc gcc-c++ openssl openssl-devel -y
yum update glib* -y

# 解压
cd /opt/soft/keepalived
tar -xvf keepalived-2.2.2.tar.gz

# 编译安装
mkdir /opt/soft/keepalived/keepalived-2.2.2/build
cd /opt/soft/keepalived/keepalived-2.2.2/build
../configure --prefix=/usr/local/keepalived-2.2.2
make && make install

3.3 环境配置

由于不是采用 yum 的方式进行安装,而是采用压缩包的方式进行安装,此时需要进行环境配置,具体如下:

Keepalived 默认会从 /etc/keepalived/keepalived.conf 路径读取配置文件,所以需要将安装后的配置文件链接到该路径:

# 创建目录
mkdir /etc/keepalived
# 备份
cp /usr/local/keepalived-2.2.2/etc/keepalived/keepalived.conf /usr/local/keepalived-2.2.2/etc/keepalived/keepalived.conf_bak
# 链接
ln -s /usr/local/keepalived-2.2.2/etc/keepalived/keepalived.conf /etc/keepalived/

将所有 Keepalived 脚本拷贝到 /etc/init.d/ 目录下:

# 编译目录中的脚本
cp /opt/soft/keepalived/keepalived-2.2.2/keepalived/etc/init.d/keepalived /etc/init.d/
# 安装目录中的脚本
cp /usr/local/keepalived-2.2.2/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/local/keepalived-2.2.2/sbin/keepalived /usr/sbin/

设置开机自启动:

chmod +x /etc/init.d/keepalived
chkconfig --add keepalived
systemctl enable keepalived.service

3.4 配置 Keepalived

这里先对 rabbit-1 上 keepalived.conf 配置文件进行修改:

vi /etc/keepalived/keepalived.conf

完整内容如下:

global_defs {
   # 路由id,主备节点不能相同
   router_id rabbit-1
}

# 自定义监控脚本
vrrp_script chk_haproxy {
    # 脚本位置
    script "/etc/keepalived/haproxy_check.sh" 
    # 脚本执行的时间间隔
    interval 5 
    weight 10
}

vrrp_instance VI_1 {
    # Keepalived的角色,MASTER 表示主节点,BACKUP 表示备份节点
    state MASTER  
    # 指定监测的网卡,可以使用 ifconfig 进行查看
    interface enp0s8
    # 虚拟路由的id,主备节点需要设置为相同
    virtual_router_id 1
    # 优先级,主节点的优先级需要设置比备份节点高
    priority 100 
    # 设置主备之间的检查时间,单位为秒 
    advert_int 1 
    # 定义验证类型和密码
    authentication { 
        auth_type PASS
        auth_pass 123456
    }

    # 调用上面自定义的监控脚本
    track_script {
        chk_haproxy
    }

    virtual_ipaddress {
        # 虚拟IP地址,可以设置多个
        10.88.9.218  
    }
}

以上配置定义了 rabbit-1上的 Keepalived 节点为 MASTER 节点,并设置对外提供服务的虚拟 IP 为 10.88.9.218。

3.5 编写HAProxy状态检测脚本

此外最主要的是定义了通过 haproxy_check.sh 来对 HAProxy 进行监控,这个脚本需要我们自行创建。

# 创建存放检测脚本的日志目录
mkdir -p /usr/local/keepalived-2.2.2/log

# 创建检测脚本
vim /etc/keepalived/haproxy_check.sh

内容如下:

#!/bin/bash

LOGFILE="/usr/local/keepalived-2.2.2/log/haproxy-check.log"
echo "[$(date)]:check_haproxy status" >> $LOGFILE

# 判断haproxy是否已经启动
HAProxyStatusA=`ps -C haproxy --no-header|wc -l`
if [ $HAProxyStatusA -eq 0 ];then
    echo "[$(date)]:启动haproxy服务......" >> $LOGFILE
    # 如果没有启动,则启动
    /usr/local/haproxy-2.3.10/sbin/haproxy -f /usr/local/haproxy-2.3.10/haproxy.cfg >> $LOGFILE 2>&1
fi

# 睡眠5秒以便haproxy完全启动
sleep5

# 如果haproxy还是没有启动,此时需要将本机的keepalived服务停掉,以便让VIP自动漂移到另外一台haproxy
HAProxyStatusB=`ps -C haproxy --no-header|wc -l`
if [ $HAProxyStatusB eq 0 ];then
    echo "[$(date)]:haproxy启动失败,睡眼5秒后haproxy服务还是没有启动,现在关闭keepalived服务,以便让VIP自动漂移到另外一台haproxy" >> $LOGFILE
    systemctl stop keepalived
fi

 创建后为其赋予执行权限:

chmod +x /etc/keepalived/haproxy_check.sh

这个脚本主要用于判断 HAProxy 服务是否正常,如果不正常且无法启动,此时就需要将本机 Keepalived 关闭,从而让虚拟 IP 漂移到备份节点。

备份节点的配置与主节点基本相同,但是需要修改其 state 为 BACKUP;同时其优先级 priority 需要比主节点低。完整配置如下:

global_defs {
   # 路由id,主备节点不能相同    
   router_id rabbit-2  
}

vrrp_script chk_haproxy {
    script "/etc/keepalived/haproxy_check.sh" 
    interval 5 
    weight 10
}

vrrp_instance VI_1 {
    # BACKUP 表示备份节点
    state BACKUP 
    interface enp0s8
    virtual_router_id 1
    # 优先级,备份节点要比主节点低
    priority 50 
    advert_int 1 
    authentication { 
        auth_type PASS
        auth_pass 123456
    }
    
    track_script {
        chk_haproxy
    }

    virtual_ipaddress {
        192.168.0.200  
    }
}

3.6 配置开机自动启动服务

将所有 Keepalived 脚本拷贝/链接到相关目录下: 

# 将编译目录中的keepalived脚本复制到/etc/init.d/目录下
cp /opt/soft/keepalived/keepalived-2.2.2/keepalived/etc/init.d/keepalived /etc/init.d/

# 将安装目录中的keepalived脚本复制到/etc/sysconfig/目录下
cp /usr/local/keepalived-2.2.2/etc/sysconfig/keepalived /etc/sysconfig/

# 将安装目录中的keepalived脚本链接到/usr/sbin/目录下
ln -s /usr/local/keepalived-2.2.2/sbin/keepalived /usr/sbin/

 设置开机自启动:

chmod +x /etc/init.d/keepalived
chkconfig --add keepalived
systemctl enable keepalived.service

 3.7 启动服务

分别在 rabbit-1 和 rabbit-2 上启动 KeepAlived 服务,命令如下: 

systemctl start keepalived

 启动后此时 rabbit-1 为主节点,可以在 rabbit-1 上使用 ip a 命令查看到虚拟 IP 的情况:

此时只有 rabbit-1 上是存在虚拟 IP 的,而 rabbit-2 上是没有的。

3.8 验证故障转移 

这里我们验证一下故障转移,因为按照我们上面的检测脚本,如果 HAProxy 已经停止且无法重启时 KeepAlived 服务就会停止,这里我们直接使用以下命令停止 Keepalived 服务: 

systemctl stop keepalived

 此时再次使用 ip a 分别查看,可以发现 rabbit-1 上的 VIP 已经漂移到 rabbit-2 上,情况如下:

此时对外服务的 VIP 依然可用,代表已经成功地进行了故障转移。

至此集群已经搭建成功,任何需要发送或者接受消息的客户端服务只需要连接到该 VIP 即可,示例如下: 

ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.0.200");

使用VIP嘗試登入rabbitmq:

在浏览器上输入http://VIP:15673/#/ 查看是否成功访问RabbitMQ管理页面:

如登入成功表示Keepalived設定成功。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

职业性格测试在求职应聘跳槽中的应用

人的性格总是千奇百怪,有的人总是想迎接挑战,超越自己,不停的奔着高处走,然而有的人总是喜欢随遇而安,踏踏实实一辈子,有份安稳的工作,有吃有喝就好。那么对于哪些喜欢迎接挑战,但又…

Adobe Camera Raw for Mac v16.1.0中文激活版

Adobe Camera Raw for Mac是一款强大的RAW格式图像编辑工具,它能够处理和编辑来自各种数码相机的原始图像。以下是关于Adobe Camera Raw for Mac的一些主要特点和功能: 软件下载:Adobe Camera Raw for Mac v16.1.0中文激活版 RAW格式支持&…

MyBatis一些常见知识点!

什么是 ORM 框架? MyBatis 有哪些优缺点? 典型回答: ORM(Object-Relational Mapping,对象关系映射)框架是一种将关系型数据库中的数据 与 应用程序中的对象进行映射的技术。它通过在程序代码中定义的类和属…

Unity类银河恶魔城学习记录1-12 PlayerComboAttack源代码 P39

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili PlayerPrimaryAttack.cs using System.Collections; using System.Collect…

七月论文审稿GPT第2.5版:微调GPT3.5 turbo 16K和llama2 13B以扩大对GPT4的优势

前言 我司自去年7月份成立大模型项目团队以来,至今已有5个项目组,其中 第一个项目组的AIGC模特生成系统已经上线在七月官网第二项目组的论文审稿GPT则将在今年3 4月份对外上线发布第三项目组的RAG知识库问答第1版则在春节之前已就绪至于第四、第五项目…

LLaVA:GPT-4V(ision) 的新开源替代品

LLaVA:GPT-4V(ision) 的新开源替代品。 LLaVA (https://llava-vl.github.io/,是 Large Language 和Visual A ssistant的缩写)。它是一种很有前景的开源生成式 AI 模型,它复制了 OpenAI GPT-4 在与图像对话方面的一些功…

(5)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—12种聚类算法说明与归纳

目录 一、12种聚类(无监督学习)算法说明和区分比较 聚类算法的类型(一) ​编辑导入函数库 加载数据集 ​编辑 (1)K-Means --Centroid models (2)Mini-Batch K-Means -- Centroid models (3)AffinityPropagation (Hierarchical) -- Connectivity models (4)Mean Shift…

最新GPT4.0使用教程,AI绘画,GPT语音对话使用,DALL-E3文生图

一、前言 ChatGPT3.5、GPT4.0、GPT语音对话、Midjourney绘画,文档对话总结DALL-E3文生图,相信对大家应该不感到陌生吧?简单来说,GPT-4技术比之前的GPT-3.5相对来说更加智能,会根据用户的要求生成多种内容甚至也可以和…

算法练习-三数之和(思路+流程图+代码)

难度参考 难度:中等 分类:数组 难度与分类由我所参与的培训课程提供,但需要注意的是,难度与分类仅供参考。且所在课程未提供测试平台,故实现代码主要为自行测试的那种,以下内容均为个人笔记,旨在…

openGauss学习笔记-214 openGauss 性能调优-确定性能调优范围

文章目录 openGauss学习笔记-214 openGauss 性能调优-确定性能调优范围214.1 性能因素214.2 调优范围确定 openGauss学习笔记-214 openGauss 性能调优-确定性能调优范围 数据库性能调优通常发生在用户对业务的执行效率不满意,期望通过调优加快业务执行的情况下。正…

机器学习的整个流程

机器学习的整个流程定义了数据科学团队执行以创建和交付机器学习模型的工作流。此外,机器学习流程还定义了团队如何协作合作,以创建最有用的预测模型。 机器学习high level的流程 机器学习流程的关键步骤包括问题探索(Problem Exploration&a…

《dx12 龙书》第四部分学习笔记——预备知识(下)

7、多重采样技术的原理 由于屏幕中显示的像素不可能是无穷小的,所以并不是任意一条直线都能在显示器上“平滑”而完美地呈现出来。即为以像素矩阵 (matrix of pixels, 可以理解为“像素2D数组”)逼近直线的方法所产生的“阶梯” &…

C# 使用 MailKit 接收邮件(附demo)

C# 使用 MailKit 接收邮件(附demo) 介绍安装包(依赖)案例简单代码 获取附件核心代码完整代码 介绍一下POP3 介绍 MailKit 是一个开源的 C# 邮件处理库,用于在应用程序中发送和接收电子邮件。它提供了一个强大且易于使…

linux实时调度

面对陌生的知识体系,应该从什么角度来 简介 一、进程管理基本概念 在单处理器系统上,在给定时刻只有一个程序可以运行,在多处理器系统上,可以真正并行运行的进程数据,取决于物理CPU的数目; 进程优先级 …

jss/css/html 相关的技术栈有哪些?

js 的技术组件有哪些?比如 jQuery vue 等 常见的JavaScript技术组件: jQuery: jQuery是一个快速、小巧且功能丰富的JavaScript库,用于简化DOM操作、事件处理、动画效果等任务。 React: React是由Facebook开发的用于构…

FPGA高端项目:IMX327 MIPI 视频解码 USB3.0 UVC 输出,提供FPGA开发板+2套工程源码+技术支持

目录 1、前言免责声明 2、相关方案推荐我这里已有的 MIPI 编解码方案 3、本 MIPI CSI-RX IP 介绍4、个人 FPGA高端图像处理开发板简介5、详细设计方案设计原理框图IMX327 及其配置MIPI CSI RX图像 ISP 处理图像缓存UVC 时序USB3.0输出架构 6、vivado工程详解FPGA逻辑设计 7、工…

docker 网络模型

一、docker的网络模型分为四种 【1】Host(与宿主机共享一个网络),宿主机的localhost 及 容器内的localhost 【2】Bridge(与宿主机共享一个局域网,有自己的网络;docker运行默认Bridge);容器内localhost不是宿主机localhost 【3】…

PyTorch 2.2 中文官方教程(五)

对抗性示例生成 原文:pytorch.org/tutorials/beginner/fgsm_tutorial.html 译者:飞龙 协议:CC BY-NC-SA 4.0 注意 点击这里下载完整的示例代码 作者: Nathan Inkawhich 如果您正在阅读本文,希望您能欣赏一些机器学习…

MySQL | DDL 里 TEXT、JSON 类型字段不设置默认值

JSON、BLOB、TEXT 等类型字段的默认值需要设置为表达式,但在旧版本(8.0.13)前只支持设置字面量,参考官方文档:MySQL :: MySQL 8.0 Reference Manual :: 11.6 Data Type Default Values。 PS:还有说是考虑减…

【刷题题解】编辑距离

给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作: 插入一个字符删除一个字符替换一个字符 这道题也是,一眼动态规划,乍一看感觉很复杂,仔细思考…