RabbitMQ “镜像模式” 集群

  • 镜像队列可以同步 queue 和 message,当主 queue 挂掉,从 queue 中会有一个变为主 queue 来接替工作。

  • 镜像队列是基于普通的集群模式的, 所以你还是得先配置普通集群, 然后才能设置镜像队列。

  • 镜像队列设置后,会分一个主节点和多个从节点,如果主节点宕机,从节点会有一个选为主节点,原先的主节点起来后会变为从节点。

    • queue 和 message 虽然会存在所有镜像队列中,但客户端读取时不论物理面连接的主节点还是从节点,都是从主节点读取数据,然后主节点再将 queue 和 message 的状态同步给从节点,因此多个客户端连接不同的镜像队列不会产生同一 message 被多次接受的情况。

1、配置集群

在普通集群的中任意节点启用策略,策略会自动同步到集群节点

1.1、通过命令设置镜像策略

语法

# set_policy [-p vhostpath] {name} {pattern} {definition} [priority]

其中:

  • NAME - 策略名,可自定义

  • PATTERN - 队列的匹配模式(正则表达式)

    • ^ 可以使用正则表达式,比如 ^queue_ 表示对队列名称以 queue_ 开头的所有队列进行镜像,而 ^ 会匹配所有的队列。
  • DEFINITION - 镜像定义,包括三个部分 ha-mode, ha-params, ha-sync-mode

    • ha-mode - high available 高可用模式,指镜像队列的模式,有效值为 all/exactly/nodes;当前策略模式为 all,即复制到所有节点,包含新增节点。all 表示在集群中所有的节点上进行镜像;exactly 表示在指定个数的节点上进行镜像,节点的个数由 ha-params 指定;nodes 表示在指定的节点上进行镜像,节点名称通过 ha-params 指定。
    • ha-params - ha-mode 模式需要用到的参数。
    • ha-sync-mode - 进行队列中消息的同步方式,有效值为 automatic 和 manual。

将所有队列设置为镜像队列,即队列会被复制到各个节点,各个节点状态一致。

[root@A ~]# rabbitmqctl set_policy xall "^" '{"ha-mode":"all"}'
Setting policy "xall" for pattern "^" to "{"ha-mode":"all"}" with priority "0" for vhost "/" ...

将符合指定规则的队列设置为镜像队列,即符合指定规则的队列会被复制到各个节点,各个节点状态一致。

[root@rabbitmq-1 ~]# rabbitmqctl set_policy -p / ha-allqueue "^isj" '{"ha-mode":"all"}'
Setting policy "ha-allqueue" for pattern "^isj" to "{"ha-mode":"all"}" with priority "0" for vhost "/" ...

注意:”^isj” 这个规则要根据自己实际情况修改,这个是指同步”isj” 开头的队列名称,配置时使用的应用于所有队列,所以表达式为”^”。

通过管理端 Admin -> Policies -> Add / update a policy 设置镜像策略。

设置好镜像模式后,在节点 A 增加了队列后,节点 B 也可以看到新增的队列。
在 RabbitMQ 管理界面 Admin -> Virtual Hosts -> Add a new virtual host 创建虚拟主机 /zm;

使用 Spring 整合的 RabbitMQ 重新测试发送和接受消息;在其中一个节点使用命令 rabbitmqctl stop_app 停掉,再测试,仍然可以发送和接受消息。

2、Nginx 实现镜像队列的负载均衡(非高可用)

虽然在程序中访问 rabbitmq-1 服务器,可以实现消息的同步,但都是 rabbitmq-1 服务器在接收消息,rabbitmq-1 太累;是否可以负载均衡,rabbitmq-1、rabbitmq-2、rabbitmq-3、rabbitmq-4 轮流接收消息,再镜像同步。

添加代理配置如下

# nginx.conf配置
[root@virtual_host ~]# cat /etc/nginx/nginx.conf
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

include /etc/nginx/conf.d/*.conf;
# MQ代理配置
[root@virtual_host ~]# cat /etc/nginx/conf.d/rabbitmq.conf 
stream {
    upstream rabbitmq {
        server 10.0.0.10:5672 max_fails=2 fail_timeout=3s weight=2;
        server 10.0.0.11:5672 max_fails=2 fail_timeout=3s weight=2;
        server 10.0.0.12:5672 max_fails=2 fail_timeout=3s weight=2;
    }
    server {
        listen 5672;
        proxy_connect_timeout 1s;
        proxy_timeout 3s;
        proxy_pass rabbitmq;
    }
}
[root@virtual_host ~]# nginx
[root@virtual_host ~]# ss -lnt
State       Recv-Q Send-Q                       Local Address:Port                                      Peer Address:Port              
LISTEN      0      128                                      *:5672                                                 *:*                  
LISTEN      0      128                                      *:111                                                  *:*                  
LISTEN      0      128                                      *:22                                                   *:*                  
LISTEN      0      128                                   [::]:111                                               [::]:*                  
LISTEN      0      128                                   [::]:22                                                [::]:*                  

这样,我们连接MQ的时候只需要连接Nginx就可以了,若Nginx并发不足,我们还可以做Nginx的高可用即可。

3、HAProxy 实现镜像队列的负载均衡

虽然在程序中访问 rabbitmq-1 服务器,可以实现消息的同步,但都是 rabbitmq-1 服务器在接收消息,rabbitmq-1 太累;是否可以负载均衡,rabbitmq-1、rabbitmq-2、rabbitmq-3、rabbitmq-4 轮流接收消息,再镜像同步。

3.1 HAProxy 简介
  • HA - High Available 高可用,Proxy - 代理。

  • HAProxy 是一款提供高可用性,负载均衡,并且基于 TCP 和 HTTP 应用的代理软件。

  • HAProxy 完全免费。

  • HAProxy 可以支持数以万计的并发连接。

  • HAProxy 可以简单又安全的整合进架构中,同时还保护 Web 服务器不被暴露到网络上。

    • 生产者 – 投递消息 –> HAProxy
    • 消费者 – 订阅消息 –> HAProxy
3.2 HAProxy 与 Nginx

OSI - Open System Interconnection 开放式系统互联,是把网络通信的工作分为 7 层,分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。

Nginx 的优点:
  • 工作在 OSI 第 7 层(应用层),可以针对 http 应用做一些分流的策略。
  • Nginx 对网络的依赖非常小,理论上能 ping 通就就能进行负载功能,屹立至今的绝对优势。
  • Nginx 安装和配置比较简单,测试起来比较方便。
  • Nginx 不仅仅是一款优秀的负载均衡器 / 反向代理软件,它同时也是功能强大的 Web 应用服务器。
HAProxy 的优点:
  • 工作在网络 4 层(传输层)和 7 层(应用层),支持 TCP 与 Http 协议。
  • 它仅仅就只是一款负载均衡软件;单纯从效率上来讲 HAProxy 更会比 Nginx 有更出色的负载均衡速度,在并发处理上也是优于 Nginx 的。
  • 支持 8 种负载均衡策略 ,支持心跳检测。

性能上 HAProxy 胜,但是功能性和便利性上 Nginx 胜。

对于 Http 协议,HAProxy 处理效率比 Nginx 高;所以,没有特殊要求的时候或者一般场景,建议使用 Haproxy 来做 Http 协议负载;如果是 Web 应用,建议使用 Nginx。

需要结合使用场景的特点来进行合理地选择。

3.3 安装和配置

HAProxy 下载:https://www.haproxy.org/#

上传到第三台 Linux 服务器(192.168.186.130)中并解压:

[root@localhost opt]# tar -zxvf haproxy-1.8.12.tar.gz

make 时需要使用 TARGET 指定内核及版本:

[root@localhost opt]# uname -r
3.10.0-514.6.2.el7.x86_64

查看目录下的 README 文件 less /opt/haproxy-1.8.12/README 可知需要根据内核版本选择编译参数:

进入目录,编译和安装:

[root@localhost opt]# cd haproxy-1.8.12
[root@localhost haproxy-1.8.12]# make TARGET=linux2628 PREFIX=/usr/local/haproxy
[root@localhost haproxy-1.8.12]# make install PREFIX=/usr/local/haproxy

安装成功后,查看版本:

[root@localhost haproxy-1.8.12]# /usr/local/haproxy/sbin/haproxy -v
HA-Proxy version 1.8.12-8a200c7 2018/06/27
Copyright 2000-2018 Willy Tarreau willy@haproxy.org

配置启动文件,复制 haproxy 文件到 /usr/sbin 目录下 ,复制 haproxy 脚本,到 /etc/init.d 目录下:

[root@localhost haproxy-1.8.12]# cp /usr/local/haproxy/sbin/haproxy /usr/sbin/
[root@localhost haproxy-1.8.12]# cp ./examples/haproxy.init /etc/init.d/haproxy
[root@localhost haproxy-1.8.12]# chmod 755 /etc/init.d/haproxy

创建系统账号:

[root@localhost haproxy-1.8.12]# useradd -r haproxy

haproxy.cfg 配置文件需要自行创建:

[root@localhost haproxy-1.8.12]# mkdir /etc/haproxy
[root@localhost haproxy-1.8.12]# vim /etc/haproxy/haproxy.cfg

添加配置信息到 haproxy.cfg
    # 全局配置
    global
        # 设置日志
        log 127.0.0.1 local0 info
        # 当前工作目录
        chroot /usr/local/haproxy
        # 用户与用户组
        user haproxy
        group haproxy
        # 运行进程 ID
        uid 99
        gid 99
        # 守护进程启动
        daemon
        # 最大连接数
        maxconn 4096

    # 默认配置
    defaults
        # 应用全局的日志配置
        log global
        # 默认的模式 mode {tcp|http|health},TCP 是 4 层,HTTP 是 7 层,health 只返回 OK
        mode tcp
        # 日志类别 tcplog
        option tcplog
        # 不记录健康检查日志信息
        option dontlognull
        # 3 次失败则认为服务不可用
        retries 3
        # 每个进程可用的最大连接数
        maxconn 2000
        # 连接超时
        timeout connect 5s
        # 客户端超时 30 秒,ha 就会发起重新连接
        timeout client 30s
        # 服务端超时 15 秒,ha 就会发起重新连接
        timeout server 15s

    # 绑定配置
    listen rabbitmq_cluster
        bind 192.168.186.130:5672
        # 配置 TCP 模式
        mode tcp
        # 简单的轮询
        balance roundrobin
        # RabbitMQ 集群节点配置,每隔 5 秒对 mq 集群做检查,2 次正确证明服务可用,3 次失败证明服务不可用
        server A 192.168.186.128:5672 check inter 5000 rise 2 fall 3
        server B 192.168.186.129:5672 check inter 5000 rise 2 fall 3

    # haproxy 监控页面地址
    listen monitor
        bind 192.168.186.130:8100
        mode http
        option httplog
        stats enable
        # 监控页面地址 http://192.168.186.130:8100/monitor
        stats uri /monitor
        stats refresh 5s

启动 HAProxy:

[root@localhost haproxy]# service haproxy start

开放对应的防火墙端口:

firewall-cmd –zone=public –add-port=5672/tcp –permanent
firewall-cmd –zone=public –add-port=8100/tcp –permanent
firewall-cmd –reload

或者:

systemctl stop firewalld

访问监控中心:http://192.168.186.130:8100/monitor

项目发消息,只需要将服务器地址修改为 192.168.186.130 即可,其余不变。

这样,所有的请求都会交给 HAProxy,然后它会负载均衡地发给每个 RabbitMQ 服务器。

  1. KeepAlived 搭建高可用的 HAProxy 集群

如果 HAProxy 服务器宕机,RabbitMQ 服务器就不可用了,所以对 HAProxy 也要做高可用的集群。

5.1 概述

Keepalived 是 Linux 的轻量级别的高可用热备解决方案。

Keepalived 的作用是检测服务器的状态,它根据 TCP / IP 参考模型的第三层、第四层、第五层交换机制检测每个服务节点的状态,如果有一台 web 服务器宕机,或工作出现故障,Keepalived 将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后 Keepalived 自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。

Keepalived 基于 VRRP - Virtual Router Redundancy Protocol 虚拟路由冗余协议协议;VRRP 是一种主备(主机和备用机)模式的协议,通过 VRRP 可以在网络发生故障时透明的进行设备切换而不影响主机之间的数据通信。

两台主机之间生成一个虚拟的 ip,称为漂移 ip,漂移 ip 由主服务器承担,一旦主服务器宕机,备份服务器就会抢夺漂移 ip,继续工作,有效的解决了群集中的单点故障。

一句话总结就是:KeepAlived 将多台路由器设备虚拟成一个设备,对外提供统一 ip(Virtual IP)。

  • 生产者 – 投递消息 –> KeepAlived

  • 消费者 – 订阅消息 –> KeepAlived

  • HAProxy 1 –> 主机 1 –> KeepAlived 虚拟 IP

  • HAProxy 2 –> 主机 2 –> KeepAlived 虚拟 IP

5.2 安装 KeepAlived

修改映射文件 vim /etc/hosts 。

3 号服务器 192.168.186.130:

127.0.0.1 C localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 C localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.186.128 A
192.168.186.129 B
192.168.186.130 C
192.168.186.131 D

4 号服务器 192.168.186.131:

127.0.0.1 D localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 D localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.186.128 A
192.168.186.129 B
192.168.186.130 C
192.168.186.131 D

注意:修改完 hosts 文件后,需要重启 Linux 服务器 reboot,否则配置不生效。

重新启动后,需要启动 haproxy:

service haproxy start

主机 C 和主机 D 都安装 keepalived:

yum install -y keepalived

主机 C 修改配置文件(删掉内容,重新创建):

[root@C ~]# rm -rf /etc/keepalived/keepalived.conf
[root@C ~]# vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
    # 非常重要,标识本机的 hostname
    router_id C
}

vrrp_script chk_haproxy {
    # 执行的脚本位置
    script "/etc/keepalived/haproxy_check.sh"
    # 检测时间间隔
    interval 2
    # 如果条件成立则权重减 20
    weight -20
}

vrrp_instance VI_1 {
    # 非常重要,标识主机,备用机 131 改为 BACKUP
    state MASTER
    # 非常重要,网卡名(ifconfig 查看)
    interface ens33
    # 非常重要,自定义,虚拟路由 ID 号(主备节点要相同)
    virtual_router_id 66
    # 优先级(0-254),一般主机的大于备机
    priority 100
    # 主备信息发送间隔,两个节点必须一致,默认 1 秒
    advert_int 1
    # 认证匹配,设置认证类型和密码,MASTER 和 BACKUP 必须使用相同的密码才能正常通信
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    track_script {
        # 检查 haproxy 健康状况的脚本
        chk_haproxy
    }
    # 简称 “VIP”
    virtual_ipaddress {
        # 非常重要,虚拟 ip,可以指定多个,以后连接 mq 就用这个虚拟ip
        192.168.186.66/24
    }
}
# 虚拟 ip 的详细配置
virtual_server 192.168.186.66 5672 {
    # 健康检查间隔,单位为秒
    delay_loop 6
    # lvs 调度算法 rr|wrr|lc|wlc|lblc|sh|dh
    lb_algo rr
    # 负载均衡转发规则。一般包括 DR, NAT, TUN 3 种
    lb_kind NAT
    # 转发协议,有 TCP 和 UDP 两种,一般用 TCP
    protocol TCP
        # 本机的真实 ip
        real_server 192.168.186.130 5672 {
        # 默认为 1, 失效为 0
        weight 1
    }
}

主机 C 创建执行脚本 vim /etc/keepalived/haproxy_check.sh

#!/bin/bash
COUNT=`ps -C haproxy --no-header |wc -l`
if [ $COUNT -eq 0 ];then
    /usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg
    sleep 2
    if [ `ps -C haproxy --no-header |wc -l` -eq 0 ];then
        killall keepalived
    fi
fi

Keepalived 组之间的心跳检查并不能察觉到 HAproxy 负载是否正常,所以需要使用此脚本。在 Keepalived 主机上,开启此脚本检测 HAproxy 是否正常工作,如正常工作,记录日志。如进程不存在,则尝试重启 HAproxy ,2 秒后检测,如果还没有,则关掉主机的 Keepalived ,此时备 Keepalived 检测到主 Keepalived 挂掉,接管 VIP,继续服务。

主机 C 给脚本文件增加执行权限(授权):

[root@C etc]# chmod +x /etc/keepalived/haproxy_check.sh

此时,安装完毕,按照上面的步骤就可以安装第二台主机 D 了(服务器 hostname 和 ip 注意要修改)。

启动 | 停止 |查看状态| 重启

service keepalived start | stop | status | restart

启动 keepalived(两台都启动):

[root@C etc]# systemctl stop firewalld
[root@C etc]# service keepalived start | stop | status | restart

查看状态:

[root@C etc]# ps -ef | grep haproxy
[root@C etc]# ps -ef | grep keepalived

查看 ip 情况 ip addr 或 ip a。

启动 keepalived 前的情况:

[root@C keepalived]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:ac:93:50 brd ff:ff:ff:ff:ff:ff
    inet 192.168.186.130/24 brd 192.168.186.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:feac:9350/64 scope link 
       valid_lft forever preferred_lft forever

启动 keepalived 后的情况:

可以看到 ens33 网卡还多绑定了一个 IP 地址。
此时,安装完毕,按照上面的步骤就可以安装第二台了(服务器 hostname 和 ip 注意要修改)。

常见的网络错误:子网掩码、网关等信息要一致。

测试 vip 和端口一起是否能提供服务

在 192.168.186.128,A 服务器上测试。

在服务器 A 执行 curl 192.168.186.130:5672 和 curl 192.168.186.66:5672 都能正常返回 AMPQ,说明安装成功。

[root@A ~]curl 192.168.186.66:5672
AMQP ## 正常提供AMQP服务,表示通过vip访问mq服务正常

测试 ip 漂移的规则

使用 ip addr 或 ip a 查看虚拟 ip。

刚开始时,C 和 D 都启动了 KeepAlived;C 是主机,所以虚拟 ip 在主机 C,表现为主机 C 显示 inet 192.168.186.66/24,而备机 D 不显示。

然后,停止主机 C 的 keepalived 使用命令:service keepalived stop,虚拟 ip 漂移到 D 节点,D 节点执行 ip a 可以看到 inet 192.168.186.66/24,而主机 C 却不显示。

接着,重新启动 C 节点的 Keepalived,虚拟 ip 依旧在 D 节点,并不会由于 C 的回归而回归。

最后,停止 D 的 Keepalived,虚拟 ip 再漂移回 C 节点。

测试项目发消息

消费者或生产者 -- 漂移 IP 66 --> KeepAlived 服务 --> [HAProxy 服务器C 130, HAProxy 服务器D 131]

HAProxy 服务器C 130 -- 负载均衡 --> [MQ 服务器A 128, MQ 服务器B 129]
HAProxy 服务器D 131 -- 负载均衡 --> [MQ 服务器A 128, MQ 服务器B 129]

测试单个 RabbitMQ 服务器:将服务器地址修改为 192.168.186.128,其余不变。

测试 HAProxy 实现多个 RabbitMQ 服务器负载均衡:将服务器地址修改为 192.168.186.130,其余不变。

测试 KeepAlived 实现的高可用的 HAProxy 集群:将服务器地址修改为 KeepAlived 的虚拟 IP 192.168.186.66,其余不变。
————————————————
版权声明:本文为CSDN博主「YMeng_Zhang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bier_zm/article/details/121212691

作者:Jeebiz  创建时间:2023-04-10 14:28
最后编辑:Jeebiz  更新时间:2024-09-23 10:03