• RabbitMQ——基于 KeepAlived + HAProxy 搭建 RabbitMQ 高可用负载均衡集群


    一、集群简介

    1.1 集群架构

    当单台 RabbitMQ 服务器的处理消息的能力达到瓶颈时,此时可以通过 RabbitMQ 集群来进行扩展,从而达到提升吞吐量的目的。

    RabbitMQ 集群是一个或多个节点的逻辑分组,集群中的每个节点都是对等的,每个节点共享所有的用户,虚拟主机,队列,交换

    器,绑定关系,运行时参数和其他分布式状态等信息。一个高可用,负载均衡的 RabbitMQ 集群架构应类似下图:

    这里对上面的集群架构做一下解释说明:

    首先一个基本的 RabbitMQ 集群不是高可用的,虽然集群共享队列,但在默认情况下,消息只会被路由到某一个节点的符合条件的队列上,

    并不会同步到其他节点的相同队列上。假设消息路由到 node1 的 my-queue 队列上,但是 node1 突然宕机了,那么消息就会丢失,想要

    解决这个问题,需要开启队列镜像,将集群中的队列彼此之间进行镜像,此时消息就会被拷贝到处于同一个镜像分组中的所有队列上。

    其次 ,RabbitMQ 集群本身并没有提供负载均衡的功能,也就是说对于一个三节点的集群,每个节点的负载可能都是不相同的,想要解决这

    个问题可以通过硬件负载均衡或者软件负载均衡的方式,这里我们选择使用 HAProxy 来进行负载均衡,当然也可以使用其他负载均衡中间

    件,如 LVS 等。HAProxy 同时支持四层和七层负载均衡,并基于单一进程的事件驱动模型,因此它可以支持非常高的井发连接数。

    接着假设我们只采用一台 HAProxy ,那么它就存在明显的单点故障的问题,所以至少需要两台 HAProxy ,同时这两台 HAProxy 之间需要

    能够自动进行故障转移,通常的解决方案就是 KeepAlived 。KeepAlived 采用 VRRP (Virtual Router Redundancy Protocol,虚拟路由冗余

    协议) 来解决单点失效的问题,它通常由一组一备两个节点组成,同一时间内只有主节点会提供对外服务,并同时提供一个虚拟的 IP 地址

    (Virtual Internet Protocol Address ,简称 VIP) 。 如果主节点故障,那么备份节点会自动接管 VIP 并成为新的主节点 ,直到原有的主节点恢复。

    最后,任何想要连接到 RabbitMQ 集群的客户端只需要连接到虚拟 IP,而不必关心集群是何种架构,示例如下:

    ConnectionFactory factory = new ConnectionFactory();
    // 假设虚拟ip为 192.168.0.200
    factory.setHost("192.168.0.200");

    1.2 部署情况

    下面我们开始进行搭建,这里我使用三台主机进行演示,主机名分别为 rabbit-1,2 和 3 ,其功能分配如下:

    • rabbit-1 服务器:部署 RabbitMQ + HAProxy + KeepAlived ;
    • rabbit-2 服务器:部署 RabbitMQ + HAProxy + KeepAlived ;
    • rabbit-3 服务器:部署 RabbitMQ

    关于 RabbitMQ 的安装步骤可以参考:RabbitMQ——安装、集群搭建、镜像队列配置


    二、HAProxy 环境搭建

    2.1 下载

    HAProxy 官方下载地址为:www.haproxy.org/#down ,如果这个网站无法访问,也可以从 src.fedoraproject.org/repo/pkgs/h… 上进行下载。

    这里我下载的是 2.x 的版本,下载后进行解压:

    tar -zxvf haproxy-2.0.3.tar.gz

    2.2 编译

    进入解压后根目录,执行下面的编译命令:

    make TARGET=linux-glibc  PREFIX=/usr/app/haproxy-2.0.3
    make install PREFIX=/usr/app/haproxy-2.0.3

    2.3 配置环境变量

    配置环境变量:

    vim /etc/profile
    export HAPROXY_HOME=/usr/app/haproxy-2.0.3
    export PATH=$PATH:$HAPROXY_HOME/sbin

    使得配置的环境变量立即生效:

    source /etc/profile

    2.4 负载均衡配置

    新建配置文件 haproxy.cfg,这里我新建的位置为:/etc/haproxy/haproxy.cfg,文件内容如下:

    # 全局配置
    global
        # 日志输出配置、所有日志都记录在本机,通过 local0 进行输出
        log 127.0.0.1 local0 info
        # 最大连接数
        maxconn 4096
        # 改变当前的工作目录
        chroot /usr/app/haproxy-2.0.3
        # 以指定的 UID 运行 haproxy 进程
        uid 99
        # 以指定的 GID 运行 haproxy 进程
        gid 99
        # 以守护进行的方式运行
        daemon
        # 当前进程的 pid 文件存放位置
        pidfile /usr/app/haproxy-2.0.3/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_admin
        bind :15673
        mode tcp
        balance roundrobin
        server node1 rabbit-1:15672
        server node2 rabbit-2:15672
        server node3 rabbit-3:15672
    
    # 绑定配置
    listen rabbitmq_cluster
        bind :5673
        # 配置TCP模式
        mode tcp
        # 采用加权轮询的机制进行负载均衡
        balance roundrobin
        # RabbitMQ 集群节点配置
        server node1 rabbit-1:5672 check inter 5000 rise 2 fall 3 weight 1
        server node2 rabbit-2:5672 check inter 5000 rise 2 fall 3 weight 1
        server node3 rabbit-3: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

    负载均衡的主要配置在 listen rabbitmq_cluster 下,这里指定负载均衡的方式为加权轮询,同时定义好健康检查机制:

    server node1 rabbit-1:5672 check inter 5000 rise 2 fall 3 weight 1

    以上配置代表对地址为 rabbit-1:5672 的 node1 节点每隔 5 秒进行一次健康检查,如果连续两次的检查结果都是正常,则认为该节点可用,

    此时可以将客户端的请求轮询到该节点上;如果连续 3 次的检查结果都不正常,则认为该节点不可用。weight 用于指定节点在轮询过程中的权重。

    2.5 启动服务

    以上搭建步骤在 rabbit-1 和 rabbit-2 上完全相同,搭建完成使用以下命令启动服务:

    haproxy -f /etc/haproxy/haproxy.cfg

    启动后可以在监控页面进行查看,端口为设置的 8100,完整地址为:http://rabbit-1:8100/stats ,页面情况如下:

    所有节点都为绿色,代表节点健康。此时证明 HAProxy 搭建成功,并已经对 RabbitMQ 集群进行监控。


    三、KeepAlived 环境搭建

    接着就可以搭建 Keepalived 来解决 HAProxy 故障转移的问题。这里我在 rabbit-1 和 rabbit-2 上安装 KeepAlived ,两台主机上的搭建的步骤完全相同,只是部分配置略有不同。

    3.1 下载

    直接从 Keepalived 官方下载所需版本,这里我下载的为 2.x 的版本。下载后进行解压:

    wget https://www.keepalived.org/software/keepalived-2.2.2.tar.gz

    3.2 编译

    安装相关依赖后进行编译:

    # 安装依赖
    yum -y install libnl libnl-devel
    yum install gcc gcc-c++ openssl openssl-devel -y
    yum update glib* -y
    # 解压
    cd /opt/soft/keepalived
    tar -xvf keepalived-2.2.2.tar.gz
    
    # 编译安装
    mkdir /opt/soft/keepalived/keepalived-2.2.2/build
    cd /opt/soft/keepalived/keepalived-2.2.2/build
    ../configure --prefix=/usr/local/keepalived-2.2.2
    make && make install

    3.3 环境配置

    由于不是采用 yum 的方式进行安装,而是采用压缩包的方式进行安装,此时需要进行环境配置,具体如下:

    Keepalived 默认会从 /etc/keepalived/keepalived.conf 路径读取配置文件,所以需要将安装后的配置文件链接到该路径:

    # 创建目录
    mkdir /etc/keepalived
    # 备份
    cp /usr/local/keepalived-2.2.2/etc/keepalived/keepalived.conf /usr/local/keepalived-2.2.2/etc/keepalived/keepalived.conf_bak
    # 链接
    ln -s /usr/local/keepalived-2.2.2/etc/keepalived/keepalived.conf /etc/keepalived/

    将所有 Keepalived 脚本拷贝到 /etc/init.d/ 目录下:

    # 编译目录中的脚本
    cp /opt/soft/keepalived/keepalived-2.2.2/keepalived/etc/init.d/keepalived /etc/init.d/
    # 安装目录中的脚本
    cp /usr/local/keepalived-2.2.2/etc/sysconfig/keepalived /etc/sysconfig/
    cp /usr/local/keepalived-2.2.2/sbin/keepalived /usr/sbin/

    设置开机自启动:

    chmod +x /etc/init.d/keepalived
    chkconfig --add keepalived
    systemctl enable keepalived.service

    3.4 配置 Keepalived

    这里先对 rabbit-1 上 keepalived.conf 配置文件进行修改:

    vi /etc/keepalived/keepalived.conf

    完整内容如下:

    global_defs {
       # 路由id,主备节点不能相同
       router_id rabbit-1
    }
    
    # 自定义监控脚本
    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 enp0s8
        # 虚拟路由的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.0.200  
        }
    }
    以上配置定义了 rabbit-1上的 Keepalived 节点为 MASTER 节点,并设置对外提供服务的虚拟 IP 为 192.168.0.200。
    3.5 编写HAProxy状态检测脚本
    此外最主要的是定义了通过 haproxy_check.sh 来对 HAProxy 进行监控,这个脚本需要我们自行创建。
    # 创建存放检测脚本的日志目录
    mkdir -p /usr/local/keepalived-2.2.2/log
    # 创建检测脚本 vim
    /etc/keepalived/haproxy_check.sh
    内容如下:
    #!/bin/bash
    
    LOGFILE="/usr/local/keepalived-2.2.2/log/haproxy-check.log"
    echo "[$(date)]:check_haproxy status" >> $LOGFILE
    
    # 判断haproxy是否已经启动
    HAProxyStatusA=`ps -C haproxy --no-header|wc -l`
    if [ $HAProxyStatusA -eq 0 ];then
        echo "[$(date)]:启动haproxy服务......" >> $LOGFILE
        # 如果没有启动,则启动
        /usr/local/haproxy-2.3.10/sbin/haproxy -f /usr/local/haproxy-2.3.10/haproxy.cfg >> $LOGFILE 2>&1
    fi
    
    # 睡眠5秒以便haproxy完全启动
    sleep5
    
    # 如果haproxy还是没有启动,此时需要将本机的keepalived服务停掉,以便让VIP自动漂移到另外一台haproxy
    HAProxyStatusB=`ps -C haproxy --no-header|wc -l`
    if [ $HAProxyStatusB eq 0 ];then
        echo "[$(date)]:haproxy启动失败,睡眼5秒后haproxy服务还是没有启动,现在关闭keepalived服务,以便让VIP自动漂移到另外一台haproxy" >> $LOGFILE
        systemctl stop keepalived
    fi

    创建后为其赋予执行权限:

    chmod +x /etc/keepalived/haproxy_check.sh
    这个脚本主要用于判断 HAProxy 服务是否正常,如果不正常且无法启动,此时就需要将本机 Keepalived 关闭,从而让虚拟 IP 漂移到备份节点。
    备份节点的配置与主节点基本相同,但是需要修改其 state 为 BACKUP;同时其优先级 priority 需要比主节点低。完整配置如下:
    global_defs {
       # 路由id,主备节点不能相同    
       router_id rabbit-2  
    }
    
    vrrp_script chk_haproxy {
        script "/etc/keepalived/haproxy_check.sh" 
        interval 5 
        weight 10
    }
    
    vrrp_instance VI_1 {
        # BACKUP 表示备份节点
        state BACKUP 
        interface enp0s8
        virtual_router_id 1
        # 优先级,备份节点要比主节点低
        priority 50 
        advert_int 1 
        authentication { 
            auth_type PASS
            auth_pass 123456
        }
        
        track_script {
            chk_haproxy
        }
    
        virtual_ipaddress {
            192.168.0.200  
        }
    }

    3.6 配置开机自动启动服务

    将所有 Keepalived 脚本拷贝/链接到相关目录下:

    # 将编译目录中的keepalived脚本复制到/etc/init.d/目录下
    cp /opt/soft/keepalived/keepalived-2.2.2/keepalived/etc/init.d/keepalived /etc/init.d/
    
    # 将安装目录中的keepalived脚本复制到/etc/sysconfig/目录下
    cp /usr/local/keepalived-2.2.2/etc/sysconfig/keepalived /etc/sysconfig/
    
    # 将安装目录中的keepalived脚本链接到/usr/sbin/目录下
    ln -s /usr/local/keepalived-2.2.2/sbin/keepalived /usr/sbin/

    设置开机自启动:

    chmod +x /etc/init.d/keepalived
    chkconfig --add keepalived
    systemctl enable keepalived.service

    3.7 启动服务

    分别在 rabbit-1 和 rabbit-2 上启动 KeepAlived 服务,命令如下:

    systemctl start keepalived

    启动后此时 rabbit-1 为主节点,可以在 rabbit-1 上使用 ip a 命令查看到虚拟 IP 的情况:

    此时只有 rabbit-1 上是存在虚拟 IP 的,而 rabbit-2 上是没有的。

    3.8 验证故障转移
    这里我们验证一下故障转移,因为按照我们上面的检测脚本,如果 HAProxy 已经停止且无法重启时 KeepAlived 服务就会停止,这里我们直接使用以下命令停止 Keepalived 服务:
    systemctl stop keepalived

    此时再次使用 ip a 分别查看,可以发现 rabbit-1 上的 VIP 已经漂移到 rabbit-2 上,情况如下:

    此时对外服务的 VIP 依然可用,代表已经成功地进行了故障转移。

    至此集群已经搭建成功,任何需要发送或者接受消息的客户端服务只需要连接到该 VIP 即可,示例如下:

    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("192.168.0.200");

    使用VIP嘗試登入rabbitmq:

    在浏览器上输入http://VIP:15673/#/查看是否成功访问RabbitMQ管理页面:

    如登入成功表示Keepalived設定成功。

    引用:

  • 相关阅读:
    grpc源码分析之域名解析
    使用swig工具为go语言与c++进行交互
    使用VS2015编译grpc_1.3.1
    在linux中编译grpc
    win32网络模型之重叠I/O
    滚动动画animate-scroll扩展
    Android Studio Gradle更新的解决办法
    MUI——页面的创建、显示、关闭
    VS2013中使用QT插件后每次重新编译问题
    Oracle Rman恢复
  • 原文地址:https://www.cnblogs.com/caoweixiong/p/14411785.html
Copyright © 2020-2023  润新知