基础信息
服务器信息
OS | IP | hostname |
---|---|---|
CentOS 7.9 | 192.168.22.202 | rabbit1 |
CentOS 7.9 | 192.168.22.203 | rabbit2 |
CentOS 7.9 | 192.168.22.204 | rabbit3 |
hosts
三台机器都如下配置:
192.168.22.202 rabbit1
192.168.22.203 rabbit2
192.168.22.204 rabbit3
每台机器还可以配上自己对应的 hosts,比如在 192.168.22.202
上:
127.0.0.1 rabbit1
- rabbit1
- rabbit2
- rabbit3
配置集群(普通模式)
这个模式下所有节点都会存储元数据,但是消息数据只有对应的节点有。假设在 rabbit1 上创建了一个队列 queue.test
,所有的节点都会有 queue.test
这个队列的基本信息,比如队列名、队列属性等等,这时,发送端发送了消息到队列 queue.test
中,那这个消息就只有 rabbit1 这个节点上的队列有,其他节点是没有的。如果 queue.test
所在节点宕掉,消息就无法正常消费了。
交换 Erlang cookie
Erlang cookie
是类似于令牌、密钥之类的东西,可以让节点和节点之间信任访问。
- rabbit1 的 Erlang cookie:
$ cat /var/lib/rabbitmq/.erlang.cookie
OOVFONDQECUSBKJTUSEL
- rabbit2 的 Erlang cookie:
$ cat /var/lib/rabbitmq/.erlang.cookie
GABAEUKVOFYRSAVUGCYF
- rabbit3 的 Erlang cookie:
$ cat /var/lib/rabbitmq/.erlang.cookie
CPQALLHLKRVGHBJOEDTX
在未交换前,三台的都是不一样的,要做的就是让三台都一样,这里选择用 rabbit1 的覆盖掉 rabbit2、rabbit3 的。
先停止所有机器上的 RabbitMQ 服务:systemctl stop rabbitmq-server
。
$ chmod 400 /var/lib/rabbitmq/.erlang.cookie
$ scp -rp /var/lib/rabbitmq/.erlang.cookie root@rabbit2:/var/lib/rabbitmq/
$ scp -rp /var/lib/rabbitmq/.erlang.cookie root@rabbit3:/var/lib/rabbitmq/
加入集群
先启动所有机器上的 RabbitMQ 服务:systemctl start rabbitmq-server
。
把 RabbitMQ 停掉,但是保留 Erlang 虚拟机。
// 仅停止要加入集群的节点,这里在 rabbit2、rabbit3 上执行
$ rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbit2 ...
进行组合,在 rabbit2、rabbit3 上执行
$ rabbitmqctl join_cluster rabbit@rabbit1
Clustering node rabbit@rabbit2 with rabbit@rabbit1
# join_cluster 加 --ram 参数表示内存存储,不加就是硬盘存储。
重新启动 rabbit2、rabbit3
$ rabbitmqctl start_app
之后就可以登录管控台查看集群状态了。
镜像队列(数据冗余)
与上面的普通模式不同的是不仅共享了元数据,也共享了队列中的消息,通过单节点就可以获取到所有队列中的消息。
set_policy
基本格式:rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]
- Name:设置策略的名称,随便起。
- Pattern:正则表达式,用来做匹配。
- Definition:策略的具体定义。
- Priority:优先级。
Definition
JSON 格式,有以下几个属性可以配置。
ha-mode
指定镜像队列的模式。可以配置以下值:
- all:表示在集群中所有的节点上进行镜像。
- exactly:表示在指定个数的节点上进行镜像,节点的个数由 ha-params 指定。
- nodes:表示在指定的节点上进行镜像,节点名称通过 ha-params 指定。
ha-params
用来填写 ha-mode
需要使用的具体值。exactly
和 nodes
需要使用。
ha-sync-mode
队列中消息的同步方式。可以配置以下值:
- automatic:自动(推荐)。
- manual:手动。
举例
Pattern
匹配所有队列,Definition
将镜像配置到集群中的所有节点。
$ rabbitmqctl set_policy ha-all "^" '{"ha-mode": "all"}'
- 名称以
pro
开始的队列镜像到集群中的任意两个节点。
$ rabbitmqctl set_policy ha-pro "^pro." '{"ha-mode": "exactly", "ha-params": 2, "ha-sync-mode": "automatic"}'
- 名称以
test
开始的队列镜像到集群中的指定两个节点。
$ rabbitmqctl set_policy ha-test "^test." '{"ha-mode": "nodes", "ha-params": ["rabbit@rabbit1", "rabbit@rabbit2"]}'
使用
配置所有队列镜像到所有节点。
$ rabbitmqctl set_policy ha-all "^" '{"ha-mode": "all"}'
查看管控台
高可用
客户端高可用
这种高可用方案主要由 SpringBoot AMQP 提供。
spring:
rabbitmq:
# 多个地址
addresses: '192.168.22.202,192.168.22.203,192.168.22.204'
服务端高可用(HAProxy)
HAProxy
是一个免费的负载均衡软件,可以运行于大部分主流的 Linux 操作系统上。
HAProxy 提供了 L4(TCP)
和 L7(HTTP)
两种负载均衡能力,具备丰富的功能。HAProxy 的社区非常活跃,版本更新快速。最关键的是,HAProxy 具备媲美商用负载均衡器的性能和稳定性。
因为 HAProxy 的上述优点,它当前不仅仅是免费负载均衡软件的首选,更几乎成为了唯一选择。
HAProxy 的核心功能
- 负载均衡:L4 和 L7 两种模式,支持
RR/静态RR/LC/IP Hash/URI Hash/URL_PARAM Hash/HTTP_HEADER Hash
等丰富的负载均衡算法。 - 健康检查:支持 TCP 和 HTTP 两种健康检查模式。
- 会话保持:对于未实现会话共享的应用集群,可通过
Insert Cookie/Rewrite Cookie/Prefix Cookie
,以及上述的多种 Hash 方式实现会话保持。 - SSL:HAProxy 可以解析 HTTPS 协议,并能够将请求解密为 HTTP 后向后端传输。
- HTTP 请求重写与重定向。
- 监控与统计:HAProxy 提供了基于 Web 的统计信息页面,展现健康状态和流量数据。基于此功能,使用者可以开发监控程序来监控 HAProxy 的状态。
安装
先关闭防火墙和 SELinux
$ systemctl stop firewalld
$ sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
$ setenforce 0
安装
$ yum install haproxy
编辑配置文件 /etc/haproxy/haproxy.cfg
。
# /etc/haproxy/haproxy.cfg
global
# Log 配置,用默认
log 127.0.0.1 local0 info
# 最大连接数
maxconn 4096
# 守护模式
daemon
defaults
# Log 使用全局的配置
log global
# 默认 TCP 模式
mode tcp
# 记录 tcp Log
option tcplog
# 不记录健康检查的日志
option dontlognull
# 检查失败几次就认为宕机
retries 3
# 最大连接数
maxconn 2000
# 连接超时
timeout connect 5s
# 客户端超时
timeout client 120s
# 服务端超时
timeout server 120s
# 配置 RabbitMQ 监听
listen rabbitmq_cluster
# 监听端口
bind :5678
# TCP 模式
mode tcp
# 负载方式: 轮询
balance roundrobin
# 负载的服务
# check inter: 间隔检查时间,单位:毫秒
# rise: 成功访问多少次就表示服务正常
# fall: 失败访问多少次就表示服务异常
# weight: 负载权重
server rabbit1 rabbit1:5672 check inter 3000 rise 2 fall 3 weight 1
server rabbit2 rabbit2:5672 check inter 3000 rise 2 fall 3 weight 1
server rabbit3 rabbit3:5672 check inter 3000 rise 2 fall 3 weight 1
# 配置 HAProxy 监控页面服务监听
listen monitor
bind :8100
mode http
option httplog
# 开启 stats
stats enable
# 地址
stats uri /rabbitmq
# 自动刷新频率
stats refresh 5s
启动
$ systemctl start haproxy
服务端高可用(Keepalived)
上面的 HAProxy 做到了客户端只需要连接 HAProxy 一个监听端口,后端自动负载 3 台 RabbitMQ 服务,但是如果 HAProxy 挂了呢?那负载的所有 RabbitMQ 也就都无法访问了。
关于 Keepalived 在此篇不属于重点,详细的就不展开说了,直接使用。
如上图的架构,在两台机器上配置好 HAProxy,并在这两台机器上配置好 Keepalived,SpringBoot 通过 Keepalived 创建出来的虚拟 IP(VIP)来访问。Keepalived 监听 HAProxy 是否还正常,如果不正常了,就把 VIP 转移到另一台配置了 Keepalived 的机器上,从而保证服务的正常。
安装使用
$ yum -y install keepalived
$ cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id rabbit1
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script chk_haproxy {
## 检查脚本
script "/etc/keepalived/haproxy_check.sh"
## 检查间隔时间
interval 2
## 条件成立权重就 -20
weight -20
}
vrrp_instance VI_1 {
state MASTER
## 网卡
interface ens33
## 虚拟路由 ID
virtual_router_id 28
## 本机 IP
mcast_src_ip 192.168.22.202
## 优先级,根据上边的 weight 调整
priority 100
## 初始化通告几个
advert_int 1
## 多个 Keepalived 之间认证,生产要做强密码
authentication {
auth_type PASS
auth_pass 1111
}
## 虚拟 IP(VIP)
virtual_ipaddress {
192.168.22.205
}
## 健康检查
track_script {
chk_haproxy
}
}
/etc/keepalived/haproxy_check.sh
:
#!/bin/bash
COUNT=`ps -C haproxy --no-header | wc -l`
if [ $COUNT -eq 0 ]; then
systemctl restart haproxy
sleep 2
if [ `ps -C haproxy --no-header | wc -l` -eq 0 ]; then
systemctl stop keepalived
fi
fi
rabbit2 上的 keepalived 就 /etc/keepalived/keepalived.conf
配置文件不同:
! Configuration File for keepalived
global_defs {
router_id rabbit2
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script chk_haproxy {
## 检查脚本
script "/etc/keepalived/haproxy_check.sh"
## 检查间隔时间
interval 2
## 条件成立权重就 -20
weight -20
}
vrrp_instance VI_1 {
state BACKUP
## 网卡
interface ens33
## 虚拟路由 ID
virtual_router_id 28
## 本机 IP
mcast_src_ip 192.168.22.203
## 优先级,根据上边的 weight 调整
priority 90
## 初始化通告几个
advert_int 1
## 多个 Keepalived 之间认证,生产要做强密码
authentication {
auth_type PASS
auth_pass 1111
}
## 虚拟 IP(VIP)
virtual_ipaddress {
192.168.22.205
}
## 健康检查
track_script {
chk_haproxy
}
}
最后启动两台机器上的 Keeplived 即可:
$ systemctl start keepalived
总结
总共有两种高可用方案,客户端高可用
和 HAProxy + Keepalived
。开一个根据自己的业务情况进行自行选配。
文章评论