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

修改IP
vim /etc/sysconfig/network-scripts/ifcfg-ens33
重启网络服务,查看ip是否配置成功
service network restart
改Centos-02为192.168.188.181

改Centos-02为192.168.188.182

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

一样的步骤:
Centos-04改为192.168.188.190
Centos-05改为192.168.188.191

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

3.2修改hosts文件
打开hosts文件
vi /etc/hosts
修改:
# rabbitmq的ip + 机器别名
192.168.188.180 rmq1
192.168.188.181 rmq2
192.168.188.182 rmq3

3.3安装Erlang
安装erlang repository
curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash

安装erlang
yum install erlang

验证,然后出来版本即可,ctro+c 俩次取消当前命令。
#验证是否安装成功
erl

3.4安装RabbitMQ
3.4.1导入两个key
rpm --import https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey
rpm --import https://packagecloud.io/gpg.key

3.4.2下载RabbitMQ脚本
curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash

3.4.3wget下载RabbitMQ
重要说明:如果提示没有wget命令,先安装wget命令。
sudo yum install wget

使用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

3.4.4安装RabbitMQ签名文件
rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc

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

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

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版本

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

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

3.4.8启用管理平台插件
启用插件后,可以可视化管理RabbitMQ
rabbitmq-plugins enable rabbitmq_management

启动应用
systemctl start rabbitmq-server
关闭防火墙、禁用防火墙
systemctl stop firewalld
systemctl disable firewalld
关闭SELINUX
getenforce
setenforce 0

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

3.6登录测试
三台RabbitMQ安装完成。

3.7RabbitMQ版本
https://github.com/rabbitmq/rabbitmq-server/releases
安装最新的RabbitMQ。

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

安装新版本
查看最新的erlang版本号

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。

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

重启
sudo service rabbitmq-server stop
sudo service rabbitmq-server start

如果账户失效,添加新账户即可
# 创建新账户
rabbitmqctl add_user longma longma
# 设置新账户为管理员
rabbitmqctl set_user_tags longma administrator
# 授权远程访问
rabbitmqctl set_permissions -p / longma ".*" ".*" ".*"
4.2rmq2、rmq3节点的hosts设置
如果跟着我的步骤改了,这里检查一下即可。

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

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下载
下载地址:
我的下载地址:
下载最新的haproxy

下载完毕后上传root目录

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

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

安装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

检查配置
cat /etc/profile

7.4负载均衡
创建配置文件:
# 创建文件夹haproxy
mkdir /etc/haproxy
# 创建haproxy.cfg文件
touch /etc/haproxy/haproxy.cfg
#编辑haproxy.cfg文件
vi /etc/haproxy/haproxy.cfg

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
提示:目录位置注意修改。

提示:主机配置。

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

修改RabbitMQ服务的hosts文件

启动RabbitMQ服务
systemctl start rabbitmq-server
关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
启动haproxy服务:
haproxy -f /etc/haproxy/haproxy.cfg

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

删除原本的配置(如果有的话)
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

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

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

9.验证故障转移
如果 haproxy1 已经停止且无法重启时,KeepAlived服务就会停止,这里我们直接使用以下命令停止 Keepalived 服务:
# 在hp1上停止keepalived
systemctl stop keepalived
此时再次使用ip addr分别查看,可以发现haproxy1上的 VIP 已经漂移到haproxy2上。此时对外服务的 VIP 依然可用,代表已经成功地进行了故障转移。

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

如果程序访问不了虚拟机部署的虚拟服务(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 = "/"
};
创作不易,感谢支持。

浙公网安备 33010602011771号