by:垃圾程序员
零、前置准备
开始之前你需要确认自己的需求,简单易用?高可用性?可扩展性?不同的方案都会有它的优点及缺点。当然如果你的应用体量还很小,我建议你直接用单体服务即可。
这是我现在的方案,不一定适用你,场景才是决定方案的唯一标准:
KeepAlived + HaProxy + 基于镜像队列的集群
小声逼逼。这是我盗的图。
前提条件:
- 在所有节点上安装了 CentOS 7.9 操作系统。
- 确保节点之间能够互相通信。可以通过配置正确的网络和主机名来实现。
一、下载对应版本的安装包
RabbitMQ的版本需要和Erlang版本对应才行,不然一堆错误,下面是RabbitMQ官方给出的对照:
erlang官网https://packagecloud.io/app/rabbitmq/erlang/search
在Erlang官网查了一下,对应Centos7的版本,最高是V23.4,这就没办法了,就它了。
rabbitmq官网https://www.rabbitmq.com/
再与上图对应查看MQ的版本也选对应区间的最大版本,也就是V3.10.7,兴高采烈的去了一趟Rabbitmq的官网,竟然是对应Centos8的版本。得嘞,再降。
然后就没有然后了,Rabbitmq官网推荐的版本没有支持Centos7的。依据不推荐的对应表,最后定在了V3.9.16。
安装包下载好,传输到对应服务器上,终于要开始安装了。
二、安装和配置 RabbitMQ
2.1安装erlang
rpm -ivh erlang-23.3.4.11-1.el7.x86_64.rpm
2.2安装RabbitMQ
rpm -ivh rabbitmq-server-3.9.16-1.el7.noarch.rpm
至此,Rabbitmq就算是完成安装,它的系统服务名叫rabbitmq-server
三、 启动RabbitMQ
3.1启动RabbitMQ的服务
sudo systemctl start rabbitmq-server
3.2查看是否已经正常启动
sudo systemctl status rabbitmq-server
对于 RabbitMQ 集群,建议在每个节点上设置开机自启动。这样可以确保在服务器重启后,集群的所有节点都能够自动启动并重新加入集群。
3.3设置开机自启动
sudo systemctl enable rabbitmq-server
四、安装Web可视化界面插件
4.1使用以下命令安装 RabbitMQ 的管理插件
sudo rabbitmq-plugins enable rabbitmq_management
4.2完成安装后,重新启动 RabbitMQ 服务
sudo systemctl restart rabbitmq-server
4.3通过浏览器访问以下 URL 来打开 RabbitMQ 的可视化管理界面
http://localhost:15672/
如果 RabbitMQ 服务器不在本地运行,则将 "localhost" 替换为相应的主机名或 IP 地址。默认情况下,用户名为 "guest",密码也为 "guest"。如果您已更改过默认凭据,请使用相应的用户名和密码进行登录。
五、配置集群
继续往下走之前,请确保所有节点上都安装了相同的 RabbitMQ 版本,确保每个节点的防火墙规则允许RabbitMQ的通信端口通过(默认是5672)。
5.1修改计算机名及映射ip
将三台服务器的名称分别修改为noede1,node2,node3
vim /etc/hostname //编辑hostname文件
node1.localdomain //修改成对应的名称
将ip对应关系添加到每台服务器上
vim /etc/hosts //修改hosts文件
192.168.100.143 node1 //将三台服务器对应的ip添加上
192.168.100.144 node2
192.168.100.145 node3
5.2配置相同Cookie
当创建一个RabbitMQ集群时,所有的节点都必须使用相同的Erlang Cookie。这样,节点之间才能互相识别并建立安全的通信连接。如果节点的Erlang Cookie不匹配,它们将无法加入同一集群,导致节点无法进行有效的通信。
如果你和我一样用rpm安装,那请到/var/lib/rabbitmq/.erlang.cookie中找打它,但如果你使用可视化界面来操作文件,则需要打开“显示隐藏文件”功能,它是隐藏的。
这里咱们无论以哪个节点上的为源头都可以,只要确保三个节点是一致的就可以。
5.3加入集群
在RabbitMQ中,有两种类型的节点:磁盘节点(disk node)和内存节点(RAM node)。
-
磁盘节点(disk node):磁盘节点是指RabbitMQ使用磁盘来持久化消息和元数据的节点。这种类型的节点适用于处理大量消息、需要长期存储消息或具有持久性需求的场景。磁盘节点的消息存储在磁盘上,因此能够在重启后恢复消息。
-
内存节点(RAM node):内存节点是指RabbitMQ将消息和元数据存储在内存中的节点。这种类型的节点适用于低延迟和高吞吐量的应用场景,因为它们可以更快速地读写消息。内存节点的消息和元数据存储在RAM中,但在重启后会丢失,因此不适用于需要持久性的场景。
通常情况下,将大部分节点配置为磁盘节点,并且至少需要一个内存节点来提供较低的延迟和更高的性能。你可以依照自己的情况来搞。
把node2和node3节点依次加入到集群中
//RabbitMQ 服务器将停止运行,关闭应用程序并释放相关的系统资源
rabbitmqctl stop_app
//执行该命令后,当前节点将以内存节点的方式加入到指定的磁盘节点
//--ram:是 join_cluster 子命令的选项之一,表示以内存节点的方式加入集群。内存节点不会保存队列和消息的数据,只参与消息的传递和处理。
rabbitmqctl join_cluster --ram rabbit@mq01
//RabbitMQ 服务器将启动运行,打开应用程序并开始接收和处理消息。
rabbitmqctl start_app
5.4验证集群
执行以下命令
sudo rabbitmqctl cluster_status
如果输出显示节点之间的连接正常,并且所有节点都是running状态,那么集群搭建成功。
5.5创建一个队列
注解:
Type(类型) :
- Classic Queue(经典队列):这是最常见的队列类型,按照先进先出(FIFO)的顺序传递消息给消费者。它适用于大多数普通的消息传递场景。
- Quorum Queue(仲裁队列):Quorum Queues 是 RabbitMQ 3.8 版本引入的一种队列类型,提供了数据副本和故障恢复的机制,以确保消息的持久性和高可用性。它使用基于 Raft 协议的仲裁机制来复制和管理队列中的消息。
- Stream Queue(流队列):Stream Queues 是 RabbitMQ 中的实验性功能,专门针对高吞吐量、持久化流式数据的场景设计。它们基于日志结构的存储形式,并通过支持分段读取来提供更高的性能和效率。
name(名称): 队列的名称,用于唯一标识队列。
Durability(持久化): 指定队列是否应该在服务器重新启动后保留。如果将其设置为 Durable,当 RabbitMQ 重新启动时,队列将被保留。
Node(节点):队列所属的节点,通过下拉可以看到集群中所有的节点。
Auto delete(自动删除): 指定当不再使用该队列时,是否自动删除队列。如果将其设置为 YES,当最后一个绑定到队列的消费者取消订阅时,队列将被自动删除。默认为 NO。
Arguments(参数): 用于传递额外的参数和选项。例如,可以使用 x-message-ttl
参数设置队列中消息的生存时间。
我们创建一个名为my_queue的队列,选配好参数点击Add queue按钮即可。
界面出现如图所示就代表创建好了。
5.6给队列配置策略
使用 rabbitmqctl
命令登录到其中一个节点的控制台
rabbitmqctl await_startup
创建一个策略来定义镜像队列的行为,这个命令会将名为 my_queue
的队列配置为镜像队列,使其在所有可用节点之间进行复制。
rabbitmqctl set_policy ha-all "^my_queue$" '{"ha-mode":"all"}'
执行完成后,如下图所示就代表策略设置成功了,这样就完成了镜像队列。
六、部署HaProxy
在两个服务器上部署。
6.1安装HaProxy
sudo yum install haproxy -y
下面的我安装的版本,后面的参数也是基于这个版本的,大家注意辨识自己的版本。
HA-Proxy version 1.5.18 2016/05/10
Copyright 2000-2016 Willy Tarreau <willy@haproxy.org>
6.2修改配置文件
一般情况下,配置文件位置在/etc/haproxy/haproxy.cfg
sudo vi /etc/haproxy/haproxy.cfg
下面是默认配置文件的一些关键部分的说明。
#---------------------------------------------------------------------
# Example configuration for a possible web application. See the
# full configuration options online.
#
# http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
# 配置日志记录到本地2(local2)
log 127.0.0.1 local2
# 设置 chroot 目录和 pid 文件位置
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
# 设置最大连接数
maxconn 4000
# 设置运行 HAProxy 的用户和组
user haproxy
group haproxy
# 以守护进程形式运行
daemon
# 开启 stats unix socket
stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
# 使用 HTTP 模式
mode http
# 记录全局日志
log global
# 不记录空连接
option dontlognull
# 开启 HTTP 请求日志
option httplog
# 关闭 HTTP 服务器连接
option http-server-close
# 开启转发,除了 127.0.0.0/8 子网的请求
option forwardfor except 127.0.0.0/8
# 开启请求重试
option redispatch
# 设置请求超时时间
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
# 设置最大连接数
maxconn 3000
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend main *:5000
# 使用 ACL 判断请求路径是否匹配静态资源路径
# 当路径以 /static、/images、/javascript、/stylesheets 开头时,匹配成功
acl url_static path_beg -i /static /images /javascript /stylesheets
# 当路径以 .jpg、.gif、.png、.css、.js 结尾时,匹配成功
acl url_static path_end -i .jpg .gif .png .css .js
# 根据匹配结果选择对应的后端
use_backend static if url_static
default_backend app
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static
# 使用 roundrobin 算法进行负载均衡
balance roundrobin
# 指定名为 static 的服务器
server static 127.0.0.1:4331 check
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
# 使用 roundrobin 算法进行负载均衡
balance roundrobin
# 指定多个服务器
server app1 127.0.0.1:5001 check
server app2 127.0.0.1:5002 check
server app3 127.0.0.1:5003 check
server app4 127.0.0.1:5004 check
接下来我们修改一下配置文件,你们要根据实际情况修改:
这三部分我都删掉了:
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
添加以下部分:
# 前端配置
frontend rabbitmq_frontend
bind *:5671 # 将前端绑定到所有 IP 地址的 5671 端口上
mode tcp # 使用 TCP 模式
default_backend rabbitmq_backend # 默认后端配置为 rabbitmq_backend
# 后端配置
backend rabbitmq_backend
mode tcp # 使用 TCP 模式
balance roundrobin # 使用轮询算法进行负载均衡
option tcp-check # 启用 TCP 健康检查
option tcp-smart-connect # 启用智能连接
timeout server 30s # 设置后端服务器超时时间为 30 秒
# 后端服务器列表
server rabbit1 192.168.134.134:5672 check # 指定一个 RabbitMQ 服务器的 IP 和端口,并启用健康检查
server rabbit2 192.168.134.135:5672 check # 指定另一个 RabbitMQ 服务器的 IP 和端口,并启用健康检查
server rabbit3 192.168.134.136:5672 check # 指定第三个 RabbitMQ 服务器的 IP 和端口,并启用健康检查
# 监听器配置
listen haproxyWeb
bind *:8999 # 监听器绑定到所有 IP 地址的 8999 端口上
stats enable # 启用统计页面功能
stats uri /haproxyWeb # 统计页面的 URI 设置为 "/haproxyWeb"
stats refresh 30s # 设置统计页面的刷新间隔为 30 秒
6.3启动HaProxy
启动命令
sudo systemctl start haproxy
查看状态命令
sudo systemctl status haproxy
查看日志命令
sudo journalctl -xeu haproxy
第一遍启动应该都会失败,日志会提示无法比绑定接口,可以搜索一下,网上有很多解决方案,注意使用其解决方案的时候辨别一下隐患。我这里就不提供解决方案了。
设置开机自启
sudo systemctl enable haproxy
6.4验证HaProxy
还记得在配置文件内配置的监听器吗,就是他,浏览器输入ip+端口+定义的路径,出现以下界面就代表可以了。
七、部署Keepalived
在两个服务器上部署,一个为主,一个为备,配置文件有不同,请注意修改。
7.1安装Keepalived
sudo yum install keepalived
7.2修改配置文件
打开配置文件
vim /etc/keepalived/keepalived.conf
修改配置
# 定义一个名为 chk_haproxy 的脚本检查项
vrrp_script chk_haproxy {
# 执行的脚本命令,用于检测 HAProxy 进程是否在运行
script "pidof haproxy"
# 脚本检查的间隔时间,单位为秒,这里设置为 2 秒
interval 2
}
# 定义一个名为 VI_1 的 VRRP 实例
vrrp_instance VI_1 {
# 在主节点上设置为 MASTER,在备份节点上设置为 BACKUP
state MASTER
# 指定网络接口,用于进行 VRRP 通信,请确认你的网卡
interface ens33
# 设置虚拟路由ID,确保同一 VRRP 组的节点具有相同的值
virtual_router_id 51
# 在主节点上设置较高的优先级,以确保其成为主节点,备份节点可以设为90
priority 100
# 广告间隔,即发送 VRRP 广告消息的时间间隔,单位为秒,这里设置为 1 秒
advert_int 1
# 用于设置认证相关参数
authentication {
# 采用密码认证
auth_type PASS
# 指定认证密码
auth_pass 123456
}
# 设置虚拟 IP 地址,即 HAProxy 使用的 IP 地址
virtual_ipaddress {
# 设置为所需的虚拟 IP 地址
192.168.134.137/24
}
# 用于监控 HAProxy 进程的脚本检查项
track_script {
# 指定之前定义的脚本检查项 chk_haproxy,以在故障时触发故障切换操作
chk_haproxy
}
}
7.3启动keepalived
启动命令
sudo systemctl start keepalived查看状态命令
sudo systemctl status keepalived设置开机自启
sudo systemctl enable keepalived
7.4验证ip漂移
查看主服务器上虚拟出来的ip
ip addr
这就是我们虚拟出来的ip,192.168.134.137
关闭当前主服务器上的HaProxy
sudo systemctl stop haproxy
去备服务器查看查看ip是否漂移
可以看到,已经漂移过来了
到这整个一套高可用方案就算是搭建完成了,当然其中还有甚多细节和配置项可以优化,根据不同情景,大家深入探索吧。
在千山万水人海相遇