3.RabbitMQ高级集群搭建(Haproxy负载均衡、Keepalived高可用)

前言

RabbitMQ集群搭建。

1.RabbitMQ集群原理

RabbitMQ这款消息队列中间件产品本身是基于Erlang编写,Erlang语言天生具备分布式特性(通过同步Erlang集群各节点的magic cookie来实现)。因此,RabbitMQ天然支持Clustering。这使得RabbitMQ本身不需要像ActiveMQ、Kafka那样通过ZooKeeper分别来实现HA方案和保存集群的元数据。集群是保证可靠性的一种方式,同时可以通过水平扩展以达到增加消息吞吐量能力的目的

5台机器,3台RabbitMQ服务器

192.168.188.180 rmq1(rabbitmq节点1)
192.168.188.181 rmq2(rabbitmq节点2)
192.168.188.182 rmq3(rabbitmq节点3)
192.168.188.190 hp1(haproxy主节点)
192.168.188.191 hp2(haproxy备份点)

2.虚拟机安装Linux

安装Centos,参看我之前的文章。

https://www.cnblogs.com/pengboke/p/18051066。

克隆5台Centos

image-20240409000640244

修改IP

vim /etc/sysconfig/network-scripts/ifcfg-ens33

重启网络服务,查看ip是否配置成功

service network restart

改Centos-02为192.168.188.181

image-20240409001616312

改Centos-02为192.168.188.182

image-20240409001104406

改完之后需要重新登录一下,这样三台RabbitMQ服务器就准备好了。

image-20240409001536261

一样的步骤:

Centos-04改为192.168.188.190

Centos-05改为192.168.188.191

image-20240409002222852

3.安装RabbitMQ

3.1设置机器别名

hostnamectl set-hostname 机器别名 --static

修改三台机器别名如下:

hostnamectl set-hostname rmq1 --static
hostnamectl set-hostname rmq2 --static
hostnamectl set-hostname rmq3 --static

查看状态

hostnamectl status

image-20240410214816916

3.2修改hosts文件

打开hosts文件

vi /etc/hosts

修改:

# rabbitmq的ip + 机器别名
192.168.188.180 rmq1 
192.168.188.181 rmq2
192.168.188.182 rmq3

image-20240410215313793

3.3安装Erlang

安装erlang repository

curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash

image-20240410215753489

安装erlang

yum install erlang

image-20240410220027568

验证,然后出来版本即可,ctro+c 俩次取消当前命令。

#验证是否安装成功
erl

image-20240410220051836

3.4安装RabbitMQ

3.4.1导入两个key

rpm --import https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey
rpm --import https://packagecloud.io/gpg.key

image-20240410220347489

3.4.2下载RabbitMQ脚本

curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash

image-20240410223257603

3.4.3wget下载RabbitMQ

重要说明:如果提示没有wget命令,先安装wget命令。

 sudo yum install wget

image-20240410223331762

使用wget下载

curl -s erlang Repositoryde的版本默认很低,安装旧版本rabbitmq没有问题,但是我安装最新的rabbitmq,具体解决看3.8

# 旧版本
# wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.13.1/rabbitmq-server-3.13.1-1.el8.noarch.rpm

wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.5/rabbitmq-server-3.8.5-1.el8.noarch.rpm

image-20240410223529499

3.4.4安装RabbitMQ签名文件

rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc

image-20240410223556533

3.4.5安装epel

epel是社区强烈打造的免费开源发行软件包版本库。

EPEL,即Extra Packages for Enterprise Linux的简称,是为企业级Linux提供的一组高质量的额外软件包,包括但不限于Red Hat Enterprise Linux (RHEL), CentOS and Scientific Linux (SL), Oracle Enterprise Linux (OEL)。(关于 : EPEL)

yum -y install epel-release

image-20240410223642744

3.4.6安装socat

socat是一个转发工具,主要实现不同接口间的转发,常用的文件、管道、设备(终端或调制解调器等)、插座(Unix,IP4,IP6 - raw,UDP,TCP)、SSL、SOCKS4客户端或代理CONNECT。

yum -y install socat

image-20240410223721336

3.4.7下载RabbitMQ

# 这是旧版本,这里我们装最新的版本
# rpm -ivh rabbitmq-server-3.8.5-1.el8.noarch.rpm

rpm -ivh rabbitmq-server-3.13.1-1.el8.noarch.rpm

如果安装最新的rabbitmq报错:依赖检测失败,转到3.8Erlong版本

image-20240411002727617

这样三台机器的最新版本erlang就安装完成了。

image-20240411003943415

三台机器的最新版本rabbitmq就安装完成了。

image-20240411005615901

3.4.8启用管理平台插件

启用插件后,可以可视化管理RabbitMQ

rabbitmq-plugins enable rabbitmq_management

image-20240411005710700

启动应用

systemctl start rabbitmq-server

关闭防火墙、禁用防火墙

systemctl stop firewalld
systemctl disable firewalld

关闭SELINUX

getenforce
setenforce 0

image-20240411005915814

3.5创建RabbitMQ用户并设置权限

(1)创建新账户

# 例子:rabbitmqctl add_user peng 123456
rabbitmqctl add_user 用户名 密码

(2)设置新账户为管理员

# 例子:rabbitmqctl set_user_tags peng administrator
rabbitmqctl set_user_tags 用户名 权限

(3)授权远程访问,分别是访问权限、读权限、写权限。

# 例子:rabbitmqctl set_permissions -p / peng ".*" ".*" ".*"
rabbitmqctl set_permissions -p / 用户名 ".*" ".*" ".*"

(4)重启服务

systemctl restart rabbitmq-server

image-20240411010531663

3.6登录测试

三台RabbitMQ安装完成。

image-20240411010732984

3.7RabbitMQ版本

https://github.com/rabbitmq/rabbitmq-server/releases

安装最新的RabbitMQ。

image-20240410223118500

3.8Erlong版本

查看最新Erlong版本

https://packagecloud.io/rabbitmq/erlang

https://github.com/rabbitmq/erlang-rpm/releases

删除旧版本

# 错误
# file /usr/lib64/erlang/releases/start_erl.data from install of erlang-26.2.3-1.el7.x86_64 conflicts with file from package erlang-23.3.4.11-1.el7.x86_64

# 删除已安装的erlang旧版本
yum remove erlang-23.3.4.11-1.el7.x86_64


# 删除已安装的RabbitMQ旧版本
# find / -name rabbit*
# rm -rf rabbitmq的目录

systemctl stop rabbitmq-server
yum list | grep rabbitmq
yum -y remove rabbitmq-server.noarch

image-20240411002526553

安装新版本

查看最新的erlang版本号

image-20240411003001456

erlang-26.2.3-1.el7.x86_64.rpm里的el7指的是Centos版本,我的是Centos7。

# 下载最新erlang
wget https://github.com/rabbitmq/erlang-rpm/releases/download/v26.2.3/erlang-26.2.3-1.el7.x86_64.rpm
# 安装erlang
rpm -ivh erlang-26.2.3-1.el7.x86_64.rpm

这样就能安装最新的版本的RabbitMQ。

image-20240411003301966

3.9yum udpate

yum -y install yum-utils
yum clean all
yum-complete-transaction --cleanup-only

package-cleanup --cleandupes
yum -y update --skip-broken

4.配置普通集群

4.1修改cookie

修改

提示:该cookie文件只读的,保存需要 :wq!

vi /var/lib/rabbitmq/.erlang.cookie

查看

cat /var/lib/rabbitmq/.erlang.cookie

image-20240411011301319

重启

sudo service rabbitmq-server stop
sudo service rabbitmq-server start

image-20240411011530479

如果账户失效,添加新账户即可

# 创建新账户
rabbitmqctl add_user longma longma
# 设置新账户为管理员
rabbitmqctl set_user_tags longma administrator
# 授权远程访问
rabbitmqctl set_permissions -p / longma ".*" ".*" ".*"

4.2rmq2、rmq3节点的hosts设置

如果跟着我的步骤改了,这里检查一下即可。

image-20240411011926189

4.3集群搭建

该实例将rmq2、rmq3加入到rmq1中,因此rmq2、rmq3都要完成以下配置

(1)停止服务
rabbitmqctl stop_app
(2)重置状态
rabbitmqctl reset
(3)节点加入 --ram内存节点
rabbitmqctl join_cluster --ram rabbit@rmq1 
(4)启动服务
rabbitmqctl start_app

image-20240411012424231

join_cluster命令有一个可选的参数--ram,该参数代表新加入的节点是内存节点,默认是磁盘节点。如果是内存节点,则所有的队列、交换器、绑定关系、用户、访问权限和vhost的元数据都将存储在内存中,如果是磁盘节点,则存储在磁盘中。内存节点可以有更高的性能,但其重启后所有配置信息都会丢失,因此RabbitMQ 要求在集群中至少有一个磁盘节点,其他节点可以是内存节点。当内存节点离开集群时,它可以将变更通知到至少一个磁盘节点;然后在其重启时,再连接到磁盘节点上获取元数据信息。除非是将 RabbitMQ用于RPC 这种需要超低延迟的场景,否则在大多数情况下,RabbitMQ 的性能都是够用的,可以采用默认的磁盘节点的形式。另外,如果节点以磁盘节点的形式加入,则需要先使用reset命令进行重置,然后才能加入现有群集,重置节点会删除该节点上存在的所有的历史资源和数据。采用内存节点的形式加入时可以略过reset这一步,因为内存上的数据本身就不是持久化的。

5.镜像节点

5.1all

如果为所有队列开启镜像配置,其语法如下:

rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'

5.2exactly

在上面指定了ha-mode 的值为 all ,代表消息会被同步到所有节点的相同队列中。这里我们之所以这样配置,因为我们本身只有三个节点,因此复制操作的性能开销比较小。如果集群有很多节点,那么此时复制的性能开销就比较大,此时需要选择合适的复制系数。通常可以遵循过半写原则,即对于一个节点数为 n 的集群,只需要同步到 n/2+1 个节点上即可。此时需要同时修改镜像策略为 exactly,并指定复制系数 ha-params,示例命令如下:

rabbitmqctl set_policy ha-two "^" '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'

5.4正则表达式

除此之外,RabbitMQ 还支持使用正则表达式来过滤需要进行镜像操作的队列,示例如下:

rabbitmqctl set_policy ha-all "^ha\." '{"ha-mode":"all"}'

6.节点下线

以上介绍的集群搭建的过程就是服务扩容的过程,如果想要进行服务缩容,即想要把某个节点剔除集群,有两种可选方式:

第一种:可以先使用rabbitmqctl stop停止该节点上的服务,然后在其他任意一个节点上执行 forget_cluster_node 命令。这里以剔除rabbit2为例,此时可以在 rabbit1或rabbit3上执行下面的命令:

rabbitmqctl forget_cluster_node rabbit@rabbit2

第二种方式:先使用 rabbitmqctl stop 停止该节点上的服务,然后再执行 rabbitmqctl reset 这会清空该节点上所有历史数据,并主动通知集群中其它节点它将要离开集群。

7.负载均衡(haproxy)

7.1下载

下载地址:

我的下载地址:

https://src.fedoraproject.org/repo/pkgs/haproxy/haproxy-2.9.4.tar.gz/sha512/a22977f7ceb24325bcbaf531d96aad7b6e8404b026405538e0512a0c7538165736e641a05720e0ca8c9fbec497f0c9935fe0a706a9923e76d34aadd879c64d36/

下载最新的haproxy

image-20240411221633531

下载完毕后上传root目录

image-20240411222353251

7.2安装

解压

tar xf haproxy-2.9.4.tar.gz

打开haproxy目录,

cd haproxy-2.9.4

安装c++依赖

# 卸载:yum remove gcc-c++
yum install gcc-c++ -y

image-20240411222749096

编译

make TARGET=linux-glibc  PREFIX=/usr/app/haproxy-2.9.4

image-20240411222921028

安装haproxy

make install PREFIX=/usr/app/haproxy-2.9.4

7.3环境变量

编辑文件

vi /etc/profile

添加配置,在profile文件最后加上如下俩行

export HAPROXY_HOME=/usr/app/haproxy-2.9.4
export PATH=$PATH:$HAPROXY_HOME/sbin

使配置环境变量立即生效

source /etc/profile

image-20240411223334384

检查配置

cat /etc/profile

image-20240411223406781

7.4负载均衡

创建配置文件:

#  创建文件夹haproxy
mkdir /etc/haproxy

# 创建haproxy.cfg文件
touch /etc/haproxy/haproxy.cfg  

#编辑haproxy.cfg文件
vi /etc/haproxy/haproxy.cfg  

image-20240411224019480

haproxy.cfg 配置如下:

global
# 日志输出配置、所有日志都记录在本机,通过 local0 进行输出
log 127.0.0.1 local0 info
# 最大连接数
maxconn 4096
# 改变当前的工作目录
chroot /usr/app/haproxy-2.9.4
# 以指定的 UID 运行 haproxy 进程
uid 99
# 以指定的 GID 运行 haproxy 进程
gid 99
# 以守护进行的方式运行
daemon
# 当前进程的 pid 文件存放位置
pidfile /usr/app/haproxy-2.9.4/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_cluster
bind :5671
# 配置TCP模式
mode tcp
# 采用加权轮询的机制进行负载均衡
balance roundrobin
# RabbitMQ 集群节点配置 5秒请求2次响应成功算正常,3次无响应算宕机。权重都是1
server node1 rmq1:5672 check inter 5000 rise 2 fall 3 weight 1
server node2 rmq2:5672 check inter 5000 rise 2 fall 3 weight 1
server node3 rmq3: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

提示:目录位置注意修改。

image-20240411224101695

提示:主机配置。

image-20240411224145119

7.5启动服务

修改haproxy机器别名

# 例子 hostnamectl set-hostname hp1 --static
# 例子 hostnamectl set-hostname hp2 --static
hostnamectl set-hostname 机器别名 --static

修改所有机器hosts文件

vi /etc/hosts

增加如下配置:

192.168.188.180 rmq1 
192.168.188.181 rmq2
192.168.188.182 rmq3
192.168.188.190 hp1
192.168.188.191 hp2

image-20240411225549109

修改RabbitMQ服务的hosts文件

image-20240411225841367

启动RabbitMQ服务

systemctl start rabbitmq-server

关闭防火墙

systemctl stop firewalld
systemctl disable firewalld

启动haproxy服务:

haproxy -f /etc/haproxy/haproxy.cfg

image-20240411230016359

8.高可用(Keepalived)

8.1安装Keepalived

我这里把hp1当做主(MASTER)、把hp2当做备份(BACKUP)

hp1:http://192.168.188.190:8100/stats

hp2:http://192.168.188.191:8100/stats

安装Keepalived

yum install -y keepalived

image-20240411230837261

删除原本的配置(如果有的话)

rm -rf /etc/keepalived/keepalived.conf

配置 HAProxy 检查

vi /etc/keepalived/keepalived.conf

keepalived.conf配置

global_defs {
   # 路由id,主备节点不能相同
   router_id node1
}
# 自定义监控脚本
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 ens33
    # 虚拟路由的id,主备节点需要设置为相同
    virtual_router_id 1
    # 优先级,主节点的优先级需要设置比备份节点高
    priority 100 
    # 设置主备之间的检查时间,单位为秒 
    advert_int 1 
    # 定义验证类型和密码
    authentication { 
        auth_type PASS
        auth_pass 123456
    }
    # 调用上面自定义的监控脚本
    track_script {
        chk_haproxy
    }
    virtual_ipaddress {
        # 虚拟IP地址,可以设置多个
        192.168.188.200  
    }
}

virtual_ipaddress就是我们最终访问的地址,不需要再去访问实际的haproxy地址和rabbitmq地址。

备份节点的state为BACKUP,并且要小于MASTER节点的priority

hp1

state MASTER 
priority 100 

hp2

state BACKUP 
priority 99 

image-20240411231230259

8.2配置Keepalived检查

编辑shell文件

vi /etc/keepalived/haproxy_check.sh

haproxy_check.sh配置:

#!/bin/bash
# 判断haproxy是否已经启动
if [ `ps -C haproxy --no-header | wc -l` -eq 0 ] ; then
    #如果没有启动,则启动
    haproxy -f /etc/haproxy/haproxy.cfg
fi
#睡眠3秒以便haproxy完全启动
sleep 3
#如果haproxy还是没有启动,此时需要将本机的keepalived服务停掉,以便让VIP自动漂移到另外一台haproxy
if [ `ps -C haproxy --no-header | wc -l` -eq 0 ]; then
    systemctl stop keepalived
fi

image-20240411232027012

8.3启动服务

给shell文件设置执行权限

chmod +x /etc/keepalived/haproxy_check.sh

分别在hp1和hp2启动 KeepAlived 服务

systemctl start  keepalived

访问:

http://192.168.188.190:8100/stats
http://192.168.188.191:8100/stats
http://192.168.188.200:8100/stats

image-20240411234132469

9.验证故障转移

如果 haproxy1 已经停止且无法重启时,KeepAlived服务就会停止,这里我们直接使用以下命令停止 Keepalived 服务:

# 在hp1上停止keepalived
systemctl stop keepalived

此时再次使用ip addr分别查看,可以发现haproxy1上的 VIP 已经漂移到haproxy2上。此时对外服务的 VIP 依然可用,代表已经成功地进行了故障转移。

image-20240412000147694

随便发了俩次消息,haproxy已监控到。

image-20240412004132746

如果程序访问不了虚拟机部署的虚拟服务(192.168.188.200),并且虚拟机网络连接使用的是Net模式,可以查看我的另一篇博客。

https://www.cnblogs.com/pengboke/p/18130348

192.168.188.200是虚拟IP

 var fac = new ConnectionFactory()
 {            
     HostName = "192.168.188.200",//IP
     Port = 5671,//端口     
     UserName = "peng",
     Password = "123456",
     VirtualHost = "/"
 };

创作不易,感谢支持。

wxzf
posted @ 2024-04-12 01:29  peng_boke  阅读(1505)  评论(0)    收藏  举报