部署RabbitMQ集群

部署RabbitMQ集群

1. 环境准备

系统版本 主机名 软件版本 模式
Ubuntu18.04.5 LTS haproxy1.example.com HAProxy 2.2.13
Lua 5.4.3
KeepAlived 1.3.9
HAProxy TCP
KeepAlived 单播
Ubuntu18.04.5 LTS haproxy2.example.com HAProxy 2.2.13
Lua 5.4.3
KeepAlived 1.3.9
HAProxy TCP
KeepAlived 单播
Ubuntu18.04.5 LTS rabbitmq1.example.com Erlang 24.0.3
Rabbit MQ 3.8.19
RabbitMQ Disk
Ubuntu18.04.5 LTS rabbitmq2.example.com Erlang 24.0.3
Rabbit MQ 3.8.19
RabbitMQ Ram
Ubuntu18.04.5 LTS rabbitmq3.example.com Erlang 24.0.3
Rabbit MQ 3.8.19
RabbitMQ Ram

HAProxy官网 RabbitMQ官网 Lua官网 KeepAlived官网

1.1. 配置主机名解析

cat /etc/hosts
127.0.0.1       localhost
127.0.1.1       ubuntu

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

172.20.1.11 rabbitmq1.example.com rabbitmq1 
172.20.1.12 rabbitmq2.example.com rabbitmq2 
172.20.1.13 rabbitmq3.example.com rabbitmq3
172.20.1.221 point.example.com point
172.20.1.211 haproxy1.example.com haproxy1
172.20.1.212 haproxy2.example.com haproxy2

2. 配置HA

2.1. 在haproxy1节点配置KeepAlived

2.1.1. 安装KeepAlived

apt install keepalived psmisc
# cp /usr/share/doc/keepalived/samples/keepalived.conf.vrrp  /etc/keepalived/keepalived.conf  // 安装好之后配置文件模板放在此处。

2.1.2. 修改配置文件

unicast_src_ip="172.20.1.211"
unicast_peer="172.20.1.212"
virtual_ipaddress="172.20.1.221"

cat << EOF > /etc/keepalived/keepalived.conf
global_defs {
   notification_email {   
     acassen@firewall.loc   # 告警邮件的接收地址
   }
   notification_email_from Alexandre.Cassen@firewall.loc  # 告警邮件的发送账号
   smtp_server smtp.qq.com  # 邮件服务器地址
   smtp_connect_timeout 30  # 连接邮件服务器的超时时间
   router_id LVS_DEVEL      # 唯一标识,默认为主机名
   vrrp_skip_check_adv_addr # 如果收到的报文和上一个报文是相同的路由器发送则跳过检测报文中的源地址。
   #vrrp_strict                         # 严格遵守VRRP协议,在以下场景需要关闭该此项 1. 没有VIP地址 2. 配置了单播邻居 3. 在VRRPv2版本中有IPv6地址。
   vrrp_iptables                        # 禁止Keepalived启动后自动生成iptable规则(如果使用Nginx和HAProxy)时没有编辑此项,则无法正常访问。
   vrrp_garp_interval 0     # ARP报文的发送延迟ms
   vrrp_gna_interval 0      # 消息发送延迟ms
}

# 定义资源监控脚本(全局唯一)
vrrp_script check_haproxy {  
    script "/etc/keepalived/haproxy_check.sh"  # 检测HAProxy状态的脚本路径
    interval 2                                 # 执行间隔 
    weight -20                                 # 检测失败之后则权重+weight的值(如:优先级100+ -20 = 80) 
    fall 3                                     # 判定服务为异常的检查次数
    rise 2                                     # 判定服务为正常的检测次数
    timeout 2                                  # 超时时间
    #user username                             # 执行检测脚本的用户和组
    #init_fail                                 # 设置默认为失败状态,在检测成功之后再转换为成功状态
}

# 定义VRouter
vrrp_instance VRouter1 {         # Vrouter1虚拟路由器的名称
    state BACKUP                 # 当前节点在此虚拟路由器上的初始状态(MASTER|BACKUP)
    interface eth0               # 绑定当前虚拟路由器使用的物理接口
    virtual_router_id 1          # 当前虚拟路由器的唯一标识(0-255)
    priority 100                 # 当前节点在此虚拟路由器中的优先级(1-254)
    advert_int 1                 # VRRP的通告间隔
    unicast_src_ip $unicast_src_ip  # 当前VRouter本机地址
    unicast_peer {
        $unicast_peer  # 当前VRouter的其他节点地址
    }
    authentication {             # 认证
        auth_type PASS           # 使用字符认证
        auth_pass P@ssW0rd       # 认证字符(仅前8位有效,可以超过8位)
    }
    track_script {
        check_haproxy
    }
    virtual_ipaddress {   # 配置虚拟IP
        $virtual_ipaddress dev eth0 label eth0:0   # 设置虚拟IP
    }
}
EOF

2.1.3. 编写健康检测脚本

cat << EOF > /etc/keepalived/haproxy_check.sh
#! /bin/bash
killall -0 haproxy
EOF
chmod +x /etc/keepalived/haproxy_check.sh

2.2. haproxy2节点配置KeepAlived

2.2.1. 安装KeepAlived

apt install keepalived psmisc

2.1.2. 修改配置文件

unicast_src_ip="172.20.1.212"
unicast_peer="172.20.1.211"
virtual_ipaddress="172.20.1.221"

cat << EOF > /etc/keepalived/keepalived.conf
global_defs {
   notification_email {   
     acassen@firewall.loc   # 告警邮件的接收地址
   }
   notification_email_from Alexandre.Cassen@firewall.loc  # 告警邮件的发送账号
   smtp_server smtp.qq.com  # 邮件服务器地址
   smtp_connect_timeout 30  # 连接邮件服务器的超时时间
   router_id LVS_DEVEL      # 唯一标识,默认为主机名
   vrrp_skip_check_adv_addr # 如果收到的报文和上一个报文是相同的路由器发送则跳过检测报文中的源地址。
   #vrrp_strict                         # 严格遵守VRRP协议,在以下场景需要关闭该此项 1. 没有VIP地址 2. 配置了单播邻居 3. 在VRRPv2版本中有IPv6地址。
   vrrp_iptables                        # 禁止Keepalived启动后自动生成iptable规则(如果使用Nginx和HAProxy)时没有编辑此项,则无法正常访问。
   vrrp_garp_interval 0     # ARP报文的发送延迟ms
   vrrp_gna_interval 0      # 消息发送延迟ms
}

# 定义资源监控脚本(全局唯一)
vrrp_script check_haproxy {  
    script "/etc/keepalived/haproxy_check.sh"  # 检测HAProxy状态的脚本路径
    interval 2                                 # 执行间隔 
    weight -20                                 # 检测失败之后则权重+weight的值(如:优先级100+ -20 = 80) 
    fall 3                                     # 判定服务为异常的检查次数
    rise 2                                     # 判定服务为正常的检测次数
    timeout 2                                  # 超时时间
    #user username                             # 执行检测脚本的用户和组
    #init_fail                                 # 设置默认为失败状态,在检测成功之后再转换为成功状态
}

# 定义VRouter
vrrp_instance VRouter1 {         # Vrouter1虚拟路由器的名称
    state BACKUP                 # 当前节点在此虚拟路由器上的初始状态(MASTER|BACKUP)
    interface eth0               # 绑定当前虚拟路由器使用的物理接口
    virtual_router_id 1          # 当前虚拟路由器的唯一标识(0-255)
    priority 100                 # 当前节点在此虚拟路由器中的优先级(1-254)
    advert_int 1                 # VRRP的通告间隔
    unicast_src_ip $unicast_src_ip  # 当前VRouter本机地址
    unicast_peer {
        $unicast_peer  # 当前VRouter的其他节点地址
    }
    authentication {             # 认证
        auth_type PASS           # 使用字符认证
        auth_pass P@ssW0rd       # 认证字符(仅前8位有效,可以超过8位)
    }
    track_script {
        check_haproxy
    }
    virtual_ipaddress {   # 配置虚拟IP
        $virtual_ipaddress dev eth0 label eth0:0   # 设置虚拟IP
    }
}
EOF

2.1.3. 编写健康检测脚本

cat << EOF > /etc/keepalived/haproxy_check.sh
#! /bin/bash
killall -0 haproxy
EOF
chmod +x /etc/keepalived/haproxy_check.sh

3. 配置LB(在两个haproxy节点)

3.1. 安装依赖包

apt install openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev gcc libreadline-dev libsystemd-dev make -y

3.2. 安装Lua

3.2.1. 下载源码包

wget http://www.lua.org/ftp/lua-5.4.3.tar.gz -O /usr/local/src/lua-5.4.3.tar.gz

3.2.2. 安装

cd /usr/local/src/ && tar zxf lua-5.4.3.tar.gz
cd lua-5.4.3 && make all test

3.2.3. 验证

./src/lua -v
Lua 5.4.3  Copyright (C) 1994-2021 Lua.org, PUC-Rio

3.3. 安装HAProxy

3.3.1. 下载源码包

wget https://repo.huaweicloud.com/haproxy/2.2/src/haproxy-2.2.13.tar.gz -O /usr/local/src/haproxy-2.2.13.tar.gz

3.3.2. 创建目录

mkdir -pv /var/lib/haproxy /etc/haproxy /usr/local/haproxy /apps

3.3.3. 解压源码包

cd /usr/local/src/ && tar -xf haproxy-2.2.13.tar.gz

3.3.4. 编译

CPUS=$(grep -c process /proc/cpuinfo)
cd haproxy-2.2.13 && \
make -j $(CPUS) ARCH=x86_64 \
TARGET=linux-glibc \
USE_GZIP=1 \
USE_PCRE=1 \
USE_OPENSSL=1 \
USE_ZLIB=1 \
USE_SYSTEMD=1 \
USE_CPU_AFFITINY=1 \
USE_LUA=1 \
LUA_INC=/usr/local/src/lua-5.4.3/src/ \
LUA_LIB=/usr/local/src/lua-5.4.3/src/ \
PREFIX=/apps/haproxy

3.3.5. 安装

make install PREFIX=/apps/haproxy

3.3.6. 编写配置文件

cat <<EOF >/etc/haproxy/haproxy.cfg
global
    maxconn 100000
    chroot /usr/local/haproxy
    stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
    uid 65534
    gid 65534
    daemon
    nbproc `grep -c process /proc/cpuinfo`
    # cpu-map 1 0
    # cpu-map 2 1
    pidfile /var/lib/haproxy/haproxy.pid
    log 127.0.0.1 local3 info
defaults
    option http-keep-alive
    option forwardfor
    maxconn 100000
    mode http
    timeout connect 120s
    timeout client 600s
    timeout server 600s
listen stats
    mode http
    bind 0.0.0.0:9999
    stats enable
    log global
    stats refresh 5s
    stats uri /haproxy-status
    stats realm HAProxy Manager
    stats auth xiaomei:123456
listen rabbitmq_admin
    bind 0.0.0.0:15672
    server rabbiqmq1 rabbitmq1.example.com:15672 check inter 2000 fall 2 rise 5
    server rabbiqmq2 rabbitmq2.example.com:15672 check inter 2000 fall 2 rise 5
    server rabbiqmq3 rabbitmq3.example.com:15672 check inter 2000 fall 2 rise 5
listen rabbitmq_cluster
    bind 0.0.0.0:5672
    option tcplog
    mode tcp
    balance leastconn
    timeout client 3h
    timeout server 3h
    server rabbiqmq1 rabbitmq1.example.com:5672 check inter 2000 fall 2 rise 5
    server rabbiqmq2 rabbitmq2.example.com:5672 check inter 2000 fall 2 rise 5
    server rabbiqmq3 rabbitmq3.example.com:5672 check inter 2000 fall 2 rise 5

EOF

3.3.7. 编写Service文件

cat << EOF > /lib/systemd/system/haproxy.service 
Description=HAProxy Load Balancer
After=syslog.target network.target

[Service]
ExecStartPre=/apps/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q 
ExecStart=/apps/haproxy/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid
ExecReload=/bin/kill -USR2 \$MAINPID
KillMode=mixed

[Install]
WantedBy=multi-user.target
EOF

3.3.8. 启动HAProxy

systemctl enable --now haproxy

4. 配置RabbitMQ集群

4.1. 各节点安装RabbitMQ(三个RabbitMQ节点)

4.1.1. 配置软件源

4.1.1.1. 添加Key
apt-key adv --keyserver "hkps://keys.openpgp.org" --recv-keys "0x0A9AF2115F4687BD29803A206B73A36E6026DFCA"
apt-key adv --keyserver "keyserver.ubuntu.com" --recv-keys "F77F1EDA57EBB1CC"
curl -1sLf 'https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey' | sudo apt-key add -
4.1.1.2. 安装apt-transport-https
apt install apt-transport-https -y
4.1.1.3. 编辑rabbitmq.list文件
cat <<EOF > /etc/apt/sources.list.d/rabbitmq.list
deb http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu bionic main
deb https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ bionic main
EOF

4.1.2. 安装Erlang

RabbitMQ和Erlang版本依赖关系

# apt-cache madison PACK_NAME // 列出指定软件包的所有可安装版本
apt update && \
apt install -y erlang-base \
    erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \
    erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \
    erlang-runtime-tools erlang-snmp erlang-ssl \
    erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl

4.1.3. 安装RabbitMQ

apt install rabbitmq-server -y --fix-missing

4.1.4. 修改Rabbit的Service文件

sed -En "/^LimitNOFILE=[0-9]+/s/[0-9]+/64000/p" /lib/systemd/system/rabbitmq-server.service
systemctl daemon-reload

4.1.5. 设置开机自启

systemctl enable rabbitmq-server

4.2. 创建RabbitMQ集群

RabbitMQ 的集群是依赖于 rlang 的集群来工作的,所以必须先构建起 erlang 的 集群环境,而 Erlang 的集群中各节点是通过一个 magic cookie 来实现的,这个 cookie 存放在 /var/lib/rabbitmq/.erlang.cookie 中,文件是 400 的权限,所以必须 保证各节点 cookie 保持一致,否则节点之间就无法通信。

4.2.1. 将加入到集群的节点停止数据写入功能并清空元数据

rabbitmqctl stop_app 
rabbitmqctl reset

4.2.2. 将节点加入到集群中并开启数据写入功能

rabbitmqctl join_cluster rabbit@rabbitmq1 --ram
rabbitmqctl start_app
# rabbitmqctl forget_cluster_node --node rabbit@rabbitmq1 rabbit@rabbitmq2  // 主节点可以使用这个命令移除集群内的节点,当前这个命令的效果是在rabbit@rabbitmq1集群中移除rabbit@rabbitmq2节点

4.2.3. 启动RabbitMQ并查看集群状态

rabbitmqctl cluster_status 
Cluster status of node rabbit@rabbitmq1 ...
Basics

Cluster name: rabbit@rabbitmq1.example.com

Disk Nodes  # 磁盘节点

rabbit@rabbitmq1

RAM Nodes  # 内存节点

rabbit@rabbitmq2
rabbit@rabbitmq3

Running Nodes

rabbit@rabbitmq1
rabbit@rabbitmq2
rabbit@rabbitmq3

Versions

rabbit@rabbitmq1: RabbitMQ 3.8.19 on Erlang 24.0.3
rabbit@rabbitmq2: RabbitMQ 3.8.19 on Erlang 24.0.3
rabbit@rabbitmq3: RabbitMQ 3.8.19 on Erlang 24.0.3

Maintenance status  # 不在维护状态的节点

Node: rabbit@rabbitmq1, status: not under maintenance
Node: rabbit@rabbitmq2, status: not under maintenance
Node: rabbit@rabbitmq3, status: not under maintenance

Alarms

(none)

Network Partitions

(none)

Listeners

Node: rabbit@rabbitmq1, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@rabbitmq1, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@rabbitmq1, interface: [::], port: 15672, protocol: http, purpose: HTTP API
Node: rabbit@rabbitmq2, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@rabbitmq2, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@rabbitmq2, interface: [::], port: 15672, protocol: http, purpose: HTTP API
Node: rabbit@rabbitmq3, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@rabbitmq3, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@rabbitmq3, interface: [::], port: 15672, protocol: http, purpose: HTTP API

Feature flags

Flag: drop_unroutable_metric, state: disabled
Flag: empty_basic_get_metric, state: disabled
Flag: implicit_default_bindings, state: enabled
Flag: maintenance_mode_status, state: enabled
Flag: quorum_queue, state: enabled
Flag: user_limits, state: enabled
Flag: virtual_host_metadata, state: enabled

4.3. 管理集群

4.3.1. 添加用户

rabbitmqctl add_user xiaomei

4.3.2. 设置用户对/具有配置、读和写的权限。

rabbitmqctl  set_permissions --vhost / xiaomei ".*" ".*" ".*"

4.3.3. 设置该用户为管理员

rabbitmqctl set_user_tags xiaomei administrator

4.3.4. 登录Web界面查看

部署RabbitMQ集群

4.4. 常用管理命令

rabbitmq SUBCMD --help  # 查看详细帮助
rabbitmq SUBCMD -h      # 查看简短帮助

4.4.1. 用户管理

新增用户 ]# rabbitmqctl add_user USER PASSWORD
删除用户 ]# rabbitmqctl delete_user USER
修改用户 ]# rabbitmqctl change_password USER PASSWORD
列出用户 ]# rabbitmqctl list_users
设置角色 ]# rabbitmqctl set_user_tags admin administrator monitoring policymaker management

4.4.2. 权限管理

设置用户权限 ]# rabbitmqctl set_permissions --vhost VHostPath USER ConfP  WriteP  ReadP
列出用户权限 ]# rabbitmqctl list_permissions
删除用户权限 ]# rabbitmqctl clear_permissions USER

4.4.3. 集群管理

4.4.3.1. 加入集群

rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster <existing cluster member> [--ram|--disc]
rabbitmqctl start_app

4.4.3.2. 删除集群内节点

在需要移除的节点上执行 ]# rabbitmqctl stop_app
在集群的主节点上面执行 ]# rabbitmqctl forget_cluster_node --node rabbit@rabbitmq1 rabbit@rabbitmq2

4.4.3.3. 查询集群状态

rabbitmqctl cluster_status 

4.4.3.4. 设置集群为镜像模式

rabbitmqctl set_policy ha-all "#" '{"ha-mode":"all"}'

4.4.4. 插件管理

rabbitmq-plugins list
rabbitmq-plugins enable <plugin-name>
rabbitmq-plugins disable <plugin-name>
# /usr/lib/rabbitmq/lib/rabbitmq_server-version/plugins 

4.4.5. 队列管理

查看所有的队列:rabbitmqctl list_queues
清除所有的队列:rabbitmqctl reset

4.4.5. 查看服务状态信息

查看集群状态:rabbitmqctl cluster_status

4.4. API

http://point.example.com:15672/api/index.html

上一篇:一文看懂Spring Boot整合Rabbit MQ实现多种模式的生产和消费


下一篇:RabbitMQ教程(六)搭建集群