基于 HAProxy + Keepalived 搭建 RabbitMQ 高可用集群

2023-05-16

RabbitMQ 集群

通常情况下,在集群中我们把每一个服务称之为一个节点,在 RabbitMQ 集群中,节点类型可以分为两种:

  • 内存节点:元数据存放于内存中。为了重启后能同步数据,内存节点会将磁盘节点的地址存放于磁盘之中,除此之外,如果消息被持久化了也会存放于磁盘之中,因为内存节点读写速度快,一般客户端会连接内存节点。
  • 磁盘节点:元数据存放于磁盘中(默认节点类型),需要保证至少一个磁盘节点,否则一旦宕机,无法恢复数据,从而也就无法达到集群的高可用目的。

PS:元数据,指的是包括队列名字属性、交换机的类型名字属性、绑定信息、vhost等基础信息,不包括队列中的消息数据。

RabbitMQ 中的集群主要有两种模式:普通集群模式和镜像队列模式。

普通集群模式

在普通集群模式下,集群中各个节点之间只会相互同步元数据,也就是说,消息数据不会被同步。那么问题就来了,假如我们连接到 A 节点,但是消息又存储在 B 节点又怎么办呢?

不论是生产者还是消费者,假如连接到的节点上没有存储队列数据,那么内部会将其转发到存储队列数据的节点上进行存储。虽然说内部可以实现转发,但是因为消息仅仅只是存储在一个节点,那么假如这节点挂了,消息是不是就没有了?因此这种普通集群模式并没有达到高可用的目的。

镜像队列模式

普通集群模式下不同节点之间只会相互同步元数据(交换机、队列、绑定关系、vhost的定义)而不会同步消息。例如,队列 1 的消息只存储在节点 1 上,节点 2 和节点 3只 同步了交换机和队列的元数据,但是没有同步消息。

假如生产者连接的是节点 3,要将消息通过交换机A路由到队列 1,最终消息还是会转发到节点 1 上存储;同理如果消费者连接的是节点 2,要从队列 1 上拉取消息,最终消息会从节点1转发到节点 2,其它节点起到一个路由的作用;如果节点1挂掉,则队列 1 的全部数据就会丢失。

镜像队列模式下,节点之间不仅仅会同步元数据,消息内容也会在镜像节点间同步,可用性更高。这种方案提升可用性的同时,也会因为同步数据带来的网络开销从而在一定程度上影响到性能。

基于 HAProxy + Keepalived 高可用集群

假如一个 RabbitMQ 集群中,有多个内存节点,我们应该连接到哪一个节点呢?这个选择的策略如果放在客户端做,那么会有很大的弊端,最严重的的就是每次扩展集群都要修改客户端代码,所以这种方式并不是很可取,所以我们在部署集群的时候就需要一个中间代理组件,这个组件要能够实现服务监控和转发,比如 Redis 中的 Sentinel(哨兵)集群模式,哨兵就可以监听 Redis 节点并实现故障转移。

在 RabbitMQ 集群中,通过 Keepalived 和 HAProxy 两个组件实现了集群的高可用性和负载均衡功能。

HAProxy

HAProxy 是一个开源的、高性能的负载均衡软件,同样可以作为负载均衡软件的还有 nginxlvs 等。 HAproxy 支持 7 层负载均衡和 4 层负载均衡。

负载均衡

所谓的 7 层负载均衡和 4 层负载均衡针对的是 OSI 模型而言,如下图所示就是一个 OSI 通信模型: 

7层应用层

应用层

HTTP、FTP、DNS、URI、HTML

TLS/SSL、SMTP、POP、IMAP、TELNET、SSH

应用程序
6层表示层
5层会话层
4层传输层

传输层

TCP、UDP、SCTP、DCCP

操作系统
3层网络层

网络层

ARP、IP、ICMP、RIP

2层数据链路层网络接口层

设备驱动程序

网络接口

1层物理层

从上表中看到,第 7 层对应应用层,第 4 层对应传输层。常用的负载均衡软件如 nginx 一般工作在第 7 层,lvs(Linux Virtual Server)一般工作在第 4 层。

  • 4 层负载:

4 层负载使用了 NAT (Network Address Translation)技术,即:网络地址转换。收到客户端请求时,可以通过修改数据包里的源 IP 和端口,然后把数据包转发到对应的目标服务器。4 层负载均衡只能根据报文中目标地址和源地址对请求进行转发,无法判断或者修改请求资源的具体类型。

  • 7 层负载:

根据客户端请求的资源路径,转发到不同的目标服务器。

高可用 HAProxy

HAProxy 虽然实现了负载均衡,但是假如只是部署一个 HAProxy,那么其本身也存在宕机的风险。一旦 HAProxy 宕机,那么就会导致整个集群不可用,所以我们也需要对 HAProxy 也实现集群,那么假如 HAProxy 也实现了集群,客户端应该连接哪一台服务呢?问题似乎又回到了起点,陷入了无限循环中...

Keepalived

为了实现 HAProxy 的高可用,需要再引入一个 Keepalived 组件,Keepalived 组件主要有以下特性:

  • 具有负载功能,可监控集群中的节点状态,如果集群中某一个节点宕机,可以实现故障转移。
  • 其本身也可以实现集群,但是只能有一个 master 节点。
  • master 节点会对外提供一个虚拟 IP,应用端只需要连接这一个 IP 就行了。可以理解为集群中的 HAProxy 节点会同时争抢这个虚拟 IP,哪个节点争抢到,就由哪个节点来提供服务。

VRRP 协议

VRRP 协议即虚拟路由冗余协议(Virtual Router Redundancy Protocol)。Keepalived 中提供的虚拟 IP 机制就属于 VRRP,它是为了避免路由器出现单点故障的一种容错协议。

搭建高可用 RabbitMQ 集群

集群环境准备

准备三台虚拟机,分别安装好 Erlang 和 RabbitMQ,可以用克隆功能。

本文服务器环境:CentOS7

[CentOS7] Install RabbitMQ Using PackageCloud Yum Repository

服务器 A:192.168.189.156 RabbitMQ 内存节点 HAPRoxy Keepalived(master)

服务器 B:192.168.189.157 RabbitMQ 内存节点 HAPRoxy Keepalived(backup)

服务器 C:192.168.189.158 RabbitMQ 磁盘节点

Keepalived: Virtual IP 192.168.189.159

集群网络架构

RabbitMQ 环境变量

环境变量配置文件 rabbitmq-env.conf 默认配置在 /etc/rabbitmq 目录,如果不存在直接创建即可,RabbitMQ 应用会自动加载。rabbitmq-env.conf 包含重写 RabbitMQ 脚本和 CLI 工具中内置默认值的环境变量。

该文件由系统 shell 解释,因此应包含一系列 shell 环境变量定义。允许使用普通的shell语法(因为文件的源代码是使用shell “.” 运算符),包括以#号开头的行注解。

按照优先级顺序,启动脚本从 shell 环境变量、rabbitmq-env.conf 和最后从内置的默认值获取它们的值。例如,对于 RABBITMQ_NODENAME 设置,首先检查 shell 环境变量中的RABBITMQ_NODENAME 如果不存在或等于空字符串,则选中 rabbitmq-env.conf 中的 NODENAME;如果它也不存在或等于空字符串,则使用启动脚本中的默认值。

rabbitmq-env.conf 中的变量名始终等于环境变量名,去掉了 RABBITMQ_ 前缀;环境变量中的 RABBITMQ_NODE_PORT 在 rabbitmq-env.conf 中的名字是 NODE_PORT。

RabbitMQ 节点

RabbitMQ 节点以节点名称作为标识,而节点名称由两部分组成:前缀 (默认是rabbit) 和主机名。当节点启动时,它会检查是否已为其分配了节点名,如果配置文件 rabbitmq-env.conf 中没有配置,则节点将解析其主机名并在其前面添加 rabbit 作为其节点名。

如果在给定的主机上运行多个节点,它们必须使用不同的前缀,例如:rabbit1@hostname 和 rabbit2@hostname。如果系统使用完全限定域名作为主机名,RabbitMQ 节点和 CLI 工具必须配置为使用长节点名称。对于服务器节点,需要将 RABBITMQ_USE_LONGNAME 环境变量设置为 true;对于 CLI 工具,必须设置 RABBITMQ_USE_LONGNAME 或 指定 –longnames 选项。例如:rabbit@centos.qq.com 其中 rabbit 为前缀,centos 是主机名,qq.com 为节点的域名。

在集群中节点名称必须是唯一的,每个节点使用节点名称来标识和联系彼此,这意味着必须解析每个节点名的主机名部分。RabbitMQ 默认节点名称是 rabbit@主机名 ,如果想自定义节点名称则需要在配置文件 /etc/rabbitmq/rabbitmq-env.conf 中配置:

NODENAME=rabbit@节点名

配置 .erlang.cookie

.erlang.cookie 文件中的字符串相当于一个密钥,一个节点要想加入某个集群,必须和所有节点的 .erlang.cookie 文件内容一致,所以通常将主节点的 .erlang.cookie 文件复制给其它节点。这里以 192.168.189.158 作为主节点,.erlang.cookie 文件位置需要在 RabbitMQ 启动日志中查看:

cat /var/log/rabbitmq/rabbit@centos158.log
2023-02-26 21:26:40.908761+08:00 [info] <0.222.0>  Starting RabbitMQ 3.10.0 on Erlang 23.3.4.11 [emu]
2023-02-26 21:26:40.908761+08:00 [info] <0.222.0>  Copyright (c) 2007-2022 VMware, Inc. or its affiliates.
2023-02-26 21:26:40.908761+08:00 [info] <0.222.0>  Licensed under the MPL 2.0. Website: https://rabbitmq.com
2023-02-26 21:26:40.912755+08:00 [info] <0.222.0> 
2023-02-26 21:26:40.912755+08:00 [info] <0.222.0>  node           : rabbit@centos158
2023-02-26 21:26:40.912755+08:00 [info] <0.222.0>  home dir       : /var/lib/rabbitmq
2023-02-26 21:26:40.912755+08:00 [info] <0.222.0>  config file(s) : (none)
2023-02-26 21:26:40.912755+08:00 [info] <0.222.0>  cookie hash    : 2cPR2mBWsaQ6fP0SWZ1QzA==
2023-02-26 21:26:40.912755+08:00 [info] <0.222.0>  log(s)         : /var/log/rabbitmq/rabbit@centos158.log
2023-02-26 21:26:40.912755+08:00 [info] <0.222.0>                 : /var/log/rabbitmq/rabbit@centos158_upgrade.log

其中 home dir 即为 .erlang.cookie 文件位置,复制主节点服务器 .erlang.cookie 文件内容到其它两个节点,使三台服务器中的 .erlang.cookie 内容一致。

配置 hosts

配置三个服务器节点的 /etc/hosts 文件:添加节点名和节点IP的映射关系

192.168.189.156 centos156
192.168.189.157 centos157
192.168.189.158 centos158

重启网络 service network restart 测试是否能够互相 ping 通。

建立集群

注:在配置 .erlang.cookie 和 hosts 之前不要启动 RabbitMQ 节点。

建立集群之前首先启动主节点 192.168.189.158 (磁盘节点)

systemctl start rabbitmq-server.service

然后分别启动其余两个子节点 (内存节点) 并加入集群:

# 启动 RabbitMQ 服务
systemctl start rabbitmq-server.service
# 暂停应用以便加入集群
rabbitmqctl stop_app
# 清除全部数据(可选)
rabbitmqctl reset
# 作为内存节点加入集群
rabbitmqctl join_cluster --ram rabbit@centos158
# 恢复应用运行
rabbitmqctl start_app

 查看集群状态

rabbitmqctl cluster_status

在任一节点的后台管理页面查看

配置镜像队列

在主节点执行如下命令:(添加一个节点,其它节点也都会有该策略)

# 设置集群所有节点及全部队列进行镜像
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'

镜像队列详细配置可参考:

RabbitMQ集群配置镜像队列 - CSDNhttps://blog.csdn.net/weixin_47026543/article/details/113563395

Classic Queue Mirroring — RabbitMQhttps://www.rabbitmq.com/ha.html

管理集群

# 退出集群
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
# 移除节点
# 关闭要移除的节点A
rabbitmqctl stop_app
# 在其他节点移除节点A
rabbitmqctl forget_cluster_node rabbit@rabbitName

负载均衡-HAProxy

安装HAProxy

在两个内存节点156和157分别安装 HAProxy

yum -y install haproxy

配置 HAProxy

cd /etc/haproxy/
cp haproxy.cfg haproxy.cfg.bak

配置文件内容全部覆盖

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
log 127.0.0.1 local2
chroot /var/lib/haproxy # 改变当前工作目录
pidfile /var/run/haproxy.pid # haproxy的pid存放路径,启动进程的用户必须有权限访问此文件
maxconn 4000 # 最大连接数,默认4000
user root # 指定haproxy运行时的用户身份
group root # 指定haproxy运行时的用户组
daemon # 创建1个进程进入deamon模式运行,此参数要求将运行模式设置为daemon
stats socket /var/lib/haproxy/stats # 创建监控所用的套接字目录
#---------------------------------------------------------------------
# defaults settings
#---------------------------------------------------------------------
# 注意:因为要使用tcp的负载,需要屏蔽掉与http相关的默认配置
defaults
mode http # 默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK
log global
# option httplog # 采用http日志格式
option dontlognull # 启用该项,日志中将不会记录空连接。所谓空连接就是在上游的负载均衡器
# option http-server-close # 每次请求完毕后主动关闭http通道
# option forwardfor except 127.0.0.0/8 # 如果后端服务器需要获得客户端真实ip需要配置的参数,可以从Http Header中获得客户端ip
option redispatch # serverId对应的服务器挂掉后,强制定向到其他健康的服务器
retries 3 # 3次连接失败就认为服务不可用,也可以通过后面设置
# timeout http-request 10s # http请求超时时间
timeout queue 1m # 队列超时时间
timeout connect 10s # 连接超时时间
timeout client 1m # 客户端连接超时时间
timeout server 1m # 服务器端连接超时时间
# timeout http-keep-alive 10s # 持久连接超时时间
timeout check 10s # 设置超时检查超时时间
maxconn 3000 # 最大连接数
###################### HAProxy统计页面配置 ######################################
listen status
bind 0.0.0.0:1080 # 监听端口
mode http # http的7层模式 
stats enable
stats refresh 30s # 每隔?秒自动刷新监控页面
stats uri /haproxy/stats # 设置监控页面的url访问路径(http://localhost:1080/haproxy/stats)
stats auth admin:123456 # 设置监控页面的用户和密码(可配置多个用户) 
stats realm (Haproxy\ statistic) # 监控页面的提示信息 
stats hide-version # 隐藏监控页面版本信息
stats admin if TRUE # 手工启用/禁用后端服务器
###################### RabbitMQ集群web管理页面负载均衡配置 #######################
listen rabbitmq_admin
bind 0.0.0.0:15670 # 监听端口
balance roundrobin
server rmq156 192.168.189.156:15672
server rmq157 192.168.189.157:15672
####################### RabbitMQ集群负载均衡配置 #################################
listen rabbitmq_cluster
bind 0.0.0.0:5670
mode tcp

# 负载均衡算法:支持 roundrobin,source,static-rr,leastconn,uri 等算法
balance roundrobin # 轮询算法

# check inter 5000 是检测心跳频率
# rise 2是2次正确认为服务器可用
# fall 3是3次失败认为服务器不可用
server rmq156 192.168.189.156:5672 check inter 5000 rise 2 fall 3
server rmq157 192.168.189.157:5672 check inter 5000 rise 2 fall 3

启动 HAProxy

分别启动156和157的 HAProxy

# yum方式
systemctl start haproxy

# 源码方式: 通过配置文件启动
haproxy -f /etc/haproxy/haproxy.cfg

启动报错

源码方式可正常启动,使用 systemctl 命令无法启动服务,查看服务状态日志如下:

一、报错信息为:cannot bind socket [0.0.0.0:xxxx]

root@centos156:/etc/haproxy # systemctl status haproxy
● haproxy.service - HAProxy Load Balancer
   Loaded: loaded (/usr/lib/systemd/system/haproxy.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since 一 2023-02-27 22:56:42 CST; 41s ago
  Process: 14563 ExecStart=/usr/sbin/haproxy-systemd-wrapper -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid $OPTIONS (code=exited, status=1/FAILURE)
 Main PID: 14563 (code=exited, status=1/FAILURE)

2月 27 22:56:42 centos156 systemd[1]: Started HAProxy Load Balancer.
2月 27 22:56:42 centos156 haproxy-systemd-wrapper[14563]: haproxy-systemd-wrapper: executing /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds
2月 27 22:56:42 centos156 haproxy-systemd-wrapper[14563]: [ALERT] 057/225642 (14566) : Starting proxy status: cannot bind socket [0.0.0.0:1080]
2月 27 22:56:42 centos156 haproxy-systemd-wrapper[14563]: [ALERT] 057/225642 (14566) : Starting proxy rabbitmq_admin: cannot bind socket [0.0.0.0:15670]
2月 27 22:56:42 centos156 haproxy-systemd-wrapper[14563]: [ALERT] 057/225642 (14566) : Starting proxy rabbitmq_cluster: cannot bind socket [0.0.0.0:5670]
2月 27 22:56:42 centos156 haproxy-systemd-wrapper[14563]: haproxy-systemd-wrapper: exit, haproxy RC=1
2月 27 22:56:42 centos156 systemd[1]: haproxy.service: main process exited, code=exited, status=1/FAILURE
2月 27 22:56:42 centos156 systemd[1]: Unit haproxy.service entered failed state.
2月 27 22:56:42 centos156 systemd[1]: haproxy.service failed.

1. 检查是否开启防火墙以及端口是否被占用

# 查看是否开启防火墙
systemctl status firewalld
# 查看端口是否被占用
netstat -tunlp | grep 1080

2. 查看 HAProxy 服务器中是否开启 Apache 或 Nginx 等 WEB 服务,如果有请先停掉这些服务。

2. 尝试关闭 selinux 或者 执行以下命令

setsebool -P haproxy_connect_any=1

3. HAProxy 配置了本机 IP 或 0.0.0.0 以外的 IP,比如虚拟 IP (Virtual IP)

1) # HAProxy 绑定非本机 IP 需要在 /etc/sysctl.conf 文件中进行配置:

# 修改内核参数
vim /etc/sysctl.conf
# 没有就新增此条记录
net.ipv4.ip_nonlocal_bind = 1
# 保存使结果生效
sysctl -p

2) #  确认是否开启内核转发功能

# 临时开启
echo 1 > /proc/sys/net/ipv4/ip_forward
# 永久生效   
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf

Haproxy启动故障:Starting proxy:cannot bind sockehttps://blog.csdn.net/qq_31889553/article/details/102852256

HAProxy cannot bind socket [0.0.0.0:8888] - Stack Overflowhttps://stackoverflow.com/questions/34793885/haproxy-cannot-bind-socket-0-0-0-08888

二、报错信息为: Cannot create pidfile /run/haproxy.pid

root@centos156:/etc/haproxy # systemctl status haproxy
● haproxy.service - HAProxy Load Balancer
   Loaded: loaded (/usr/lib/systemd/system/haproxy.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since 一 2023-02-27 23:20:13 CST; 9s ago
  Process: 16010 ExecStart=/usr/sbin/haproxy-systemd-wrapper -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid $OPTIONS (code=exited, status=1/FAILURE)
 Main PID: 16010 (code=exited, status=1/FAILURE)

2月 27 23:20:13 centos156 systemd[1]: Started HAProxy Load Balancer.
2月 27 23:20:13 centos156 haproxy-systemd-wrapper[16010]: haproxy-systemd-wrapper: executing /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds
2月 27 23:20:13 centos156 haproxy-systemd-wrapper[16010]: [ALERT] 057/232013 (16012) : [/usr/sbin/haproxy.main()] Cannot create pidfile /run/haproxy.pid
2月 27 23:20:13 centos156 haproxy-systemd-wrapper[16010]: haproxy-systemd-wrapper: exit, haproxy RC=1
2月 27 23:20:13 centos156 systemd[1]: haproxy.service: main process exited, code=exited, status=1/FAILURE
2月 27 23:20:13 centos156 systemd[1]: Unit haproxy.service entered failed state.
2月 27 23:20:13 centos156 systemd[1]: haproxy.service failed.

1. 检查 haproxy.cfg 配置的用户 user 是否拥有 root 权限

2. 尝试删除 /run/haproxy.pid 并重新启动 HAProxy 服务

测试 HAProxy

测试浏览器能正常访问以下两个地址的 RabbitMQ 管理页面

192.168.189.156:15670
192.168.189.157:15670

测试浏览器能正常访问以下两个地址的 HAProxy 监控页面 (amdin/123456)

192.168.189.156:1080/haproxy/stats
192.168.189.157:1080/haproxy/stats 

主备-Keepalived

安装Keepalived

yum install -y keepalived

配置Keepalived

cd /etc/keepalived
cp keepalived.conf keepalived.conf.bak

156 作为主机 master 配置如下:

global_defs {
     router_id NodeA      # 路由ID:主机与备机不能相同
     script_user root
     enable_script_security
}

vrrp_script chk_haproxy { # 自定义监控脚本
    script "/etc/keepalived/check_haproxy.sh"
    interval 5
    weight 2
}

vrrp_instance VI_1 {
    state MASTER         # 这里标记为主机Master
    interface ens33      # 这里的必须和你的网卡一致,ipconfig获得
    virtual_router_id 1  # 这里表示路由的唯一标识与备机一致
    priority 100         # 配置优先级:备机要小于主机
    advert_int 1         # 设置主备之间的检查时间,单位为s
    authentication {
        auth_type PASS  # 配置认证方式
        auth_pass root  # 配置认证密码
    }
    virtual_ipaddress { # 配置虚拟ip地址,主备需保持一致,可设置多个
        192.168.189.159
    }

    track_script {
        chk_haproxy
    }
}

157 作为备机 backup 配置如下:

global_defs {
     router_id NodeB      # 路由ID:主机与备机不能相同
     script_user root
     enable_script_security
}

vrrp_script chk_haproxy { # 自定义监控脚本
    script "/etc/keepalived/check_haproxy.sh"
    interval 5
    weight 2
}

vrrp_instance VI_1 {
    state BACKUP         # 这里标记为备机Backup
    interface ens33      # 这里的必须和你的网卡一致,ipconfig获得
    virtual_router_id 1  # 这里表示路由的唯一标识与备机一致
    priority 50          # 配置优先级:备机要小于主机
    advert_int 1         # 设置主备之间的检查时间,单位为s
    authentication {
        auth_type PASS  # 配置认证方式
        auth_pass root  # 配置认证密码
    }
    virtual_ipaddress { # 配置虚拟ip地址,主备需保持一致,可设置多个
        192.168.189.159
    }

    track_script {
        chk_haproxy
    }
}

编写监控脚本

vim /etc/keepalived/check_haproxy.sh
#!/bin/bash
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ];then
service haproxy start
fi
sleep 2
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ];then
service keepalived stop
fi
# 添加可执行权限
chmod 755 /etc/keepalived/check_haproxy.sh

check_haproxy.sh 脚本作用

如果 HAProxy 服务挂了,尝试重启;如果重启不成功,则关闭 Keepalived 服务,自动切换到 backup。

启动 Keepalived

先启动 156 master 再启动 157 backup

service keepalived start

监测 Keepalived

1. 查看 Keepalived 状态

service keepalived status

2. 查看 Keepalived 日志输出

tail -200f /var/log/messages

3. 查看添加的虚拟IP (master)

ip add show

4. master 模拟异常关闭

service keepalived stop

master 关闭后对应的虚拟IP也会消失,backup 成为新的 master,异常 master 重启后会重新恢复为 master 。

5.  master 模拟 HAProxy 异常关闭

service haproxy stop

测试 HAProxy 异常关闭后,打印 Keepalived 日志查看监控脚本是否正常执行。

# 打印 Keepalived 日志
tail -200f /var/log/messages
# 正常启动脚本日志信息(注意succeeded)
Feb 28 03:42:05 centos156 Keepalived_vrrp[37334]: VRRP_Instance(VI_1) Entering MASTER STATE
Feb 28 03:42:05 centos156 Keepalived_vrrp[37334]: VRRP_Instance(VI_1) setting protocol VIPs.
Feb 28 03:42:05 centos156 Keepalived_vrrp[37334]: Sending gratuitous ARP on ens33 for 192.168.189.159
Feb 28 03:42:05 centos156 Keepalived_vrrp[37334]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.189.159
Feb 28 03:42:05 centos156 Keepalived_vrrp[37334]: Sending gratuitous ARP on ens33 for 192.168.189.159
Feb 28 03:42:05 centos156 Keepalived_vrrp[37334]: Sending gratuitous ARP on ens33 for 192.168.189.159
Feb 28 03:42:05 centos156 Keepalived_vrrp[37334]: Sending gratuitous ARP on ens33 for 192.168.189.159
Feb 28 03:42:05 centos156 Keepalived_vrrp[37334]: Sending gratuitous ARP on ens33 for 192.168.189.159
Feb 28 03:42:05 centos156 avahi-daemon[816]: Registering new address record for 192.168.189.159 on ens33.IPv4.
Feb 28 03:42:06 centos156 Keepalived_vrrp[37334]: VRRP_Script(chk_haproxy) succeeded
Feb 28 03:42:07 centos156 Keepalived_vrrp[37334]: VRRP_Instance(VI_1) Changing effective priority from 100 to 102
Feb 28 03:42:10 centos156 Keepalived_vrrp[37334]: Sending gratuitous ARP on ens33 for 192.168.189.159
Feb 28 03:42:10 centos156 Keepalived_vrrp[37334]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on ens33 for 192.168.189.159
Feb 28 03:42:10 centos156 Keepalived_vrrp[37334]: Sending gratuitous ARP on ens33 for 192.168.189.159
Feb 28 03:42:10 centos156 Keepalived_vrrp[37334]: Sending gratuitous ARP on ens33 for 192.168.189.159
Feb 28 03:42:10 centos156 Keepalived_vrrp[37334]: Sending gratuitous ARP on ens33 for 192.168.189.159
Feb 28 03:42:10 centos156 Keepalived_vrrp[37334]: Sending gratuitous ARP on ens33 for 192.168.189.159

解决 Keepalived 监测脚本一直不执行https://blog.csdn.net/Bb15070047748/article/details/106276491

解决Keepalived脚本启动时warning、unsafe、not executable - CSDNhttps://blog.csdn.net/Kangyucheng/article/details/110122893

测试虚拟 IP

浏览器通过虚拟IP访问能正常打开 RabbitMQ 管理页面 和 HAProxy 监控页面

应用访问集群

1. IP 为 Keepalived 中配置的虚拟IP

2. PORT 为 RabbitMQ 默认的 5672

3. 账号密码同 RabbitMQ

参考资料

单机RabbitMQ集群的搭建及高可用集群原理分析 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/350446326

高可用RabbitMQ集群的搭建和使用 - 劈天造陆 - 博客园 (cnblogs.com)https://www.cnblogs.com/java-spring/p/8855862.html

HAProxy安装与配置 - 我爱吃芹菜~ - 博客园 (cnblogs.com)https://www.cnblogs.com/leixixi/p/14749322.html

rabbitmq搭建集群踩坑记 - 腾讯云开发者社区-腾讯云 (tencent.com)https://cloud.tencent.com/developer/article/1683781

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于 HAProxy + Keepalived 搭建 RabbitMQ 高可用集群 的相关文章

  • 为什么 Celery 工作人员给出“OSError:套接字已关闭”

    我的与rabbitMQ一起工作的celery工作人员在工作几分钟后不断给我一个套接字错误 见下文 我想知道问题的主要原因是什么 我认为这可能是防火墙 但是 禁用防火墙并没有解决问题 我正在 Windows 10 机器上工作 C Users
  • 组在 RabbitMQ 中接收消息,最好使用 Spring AMQP?

    我正在从服务 S 接收消息 该服务将每个单独的属性更改作为单独的消息发布到实体 一个人为的例子是这样的实体 Person id 123 name Something address 如果姓名和地址在同一交易中更新 则 S 将发布两条消息 P
  • 与 RabbitMQ 相比,Amazon SQS 的性能较慢

    我想在我的 Web 应用程序中集成消息队列中间层 我测试了 Rabbitmq 和 Amazon SQS 但发现 Amazon SQS 速度很慢 我在 Amazon SQS 中每秒收到 80 个请求 而在 Rabbitmq 中每秒收到 200
  • 在点网核心应用程序中使用 RabbitMQ 跳过 MassTransit 中的队列

    我有三个项目 一个是Dot net core MVC 两个是API项目 MVC 正在调用一个 API 来获取用户详细信息 当询问用户详细信息时 我通过 MassTransit 向队列发送消息 我看到跳过队列 第三个项目中有消费者 即API项
  • 我应该在 Django 项目中使用 Celery 还是 Carrot?

    我有点困惑我应该使用哪一个 我认为两者都可以 但其中一个比另一个更好或更合适吗 http github com ask carrot tree master http github com ask carrot tree master ht
  • 在 Red Hat 上安装 RabbitMQ - 错误的 Erlang 版本

    我正在尝试按照以下说明在 Red Hat Enterprise Linux 7 64 位工作站版本 的评估虚拟机上安装 RabbitMQhttps www rabbitmq com install rpm html https www ra
  • 如何在 Node js 中保持分叉的子进程处于活动状态

    我想创建一个像带有node的foreverjs一样运行的rabbitmq cli 它可以生成 child process 并使其在后台运行 并且可以随时与 child process 进行通信 我面临的问题是 当主 cli 程序退出时 ch
  • 每次发布后我应该关闭通道/连接吗?

    我在 Node js 中使用 amqplib 但我不清楚代码中的最佳实践 基本上 我当前的代码调用amqp connect 当 Node 服务器启动时 然后为每个生产者和每个消费者使用不同的通道 而不会真正关闭它们中的任何一个 我想知道这是
  • Django 1.6 + RabbitMQ 3.2.3 + Celery 3.1.9 - 为什么我的 celery 工作人员会死掉:WorkerLostError:工作人员过早退出:信号 11 (SIGSEGV)

    这似乎解决了一个非常相似的问题 但并没有给我足够的洞察力 https github com celery billiard issues 101 https github com celery billiard issues 101听起来尝
  • Spring AMQP RabbitMQ 如何直接发送到Queue而不需要Exchange

    我正在使用 Spring AMQP 和 Rabbitmq 模板 如何直接将消息发送到队列而不使用Exchange 我该怎么做 我该怎么做 你不能 发布者不知道队列 只是交换和路由密钥 但是 所有队列都绑定到默认交换器 以队列名称作为其路由键
  • 为什么需要消息队列来与 Web 套接字聊天?

    我在互联网上看到了很多使用 Web 套接字和 RabbitMQ 进行聊天的示例 https github com videlalvaro rabbitmq chat https github com videlalvaro rabbitmq
  • 多个队列在一个通道中消耗

    我使用rabbitMq 来管理和使用队列 我有多个队列 它们的数量并不具体 我使用直接交换来发布消息 我怎样才能仅使用一个队列来消费每个队列的所有消息 基于routing key 渠道 此时我假设我有 5 个队列 我使用了 for 循环并为
  • 死信交换 RabbitMQ 丢弃消息

    我正在尝试在 RabbitMQ 中实现 dlx 队列 场景很简单 我有 2 个队列 1 活着 2 死亡 x dead letter exchange 立即 x message ttl 5000 以及 立即 交换 这必然是 1 活着 我尝试运
  • springrabbitmq:无法将id设置为属性?

    我有一个属性文件 其中包含队列 其值为queue name 如果我在其他请使用该属性 那么它可以工作 但如果我在 id 上使用它 那么它会失败
  • 使用 RabbitMq 锁定和批量获取消息

    我正在尝试以一种更非常规的方式使用 RabbitMq 尽管此时我可以根据需要选择任何其他消息队列实现 消费者不会将 Rabbit 推送消息留给我的消费者 而是连接到一个队列并获取一批 N 条消息 在此期间它会消费一些消息 并可能拒绝一些消息
  • Celery 与rabbitmq 创建结果多个队列

    我已经用 RabbitMQ 安装了 Celery 问题是 对于返回的每个结果 Celery 都会在 Rabbit 中创建队列 并在交换 celeryresults 中使用任务 ID 我仍然想得到结果 但在一个队列上 我的芹菜配置 from
  • AMQP如何克服直接使用TCP的困难?

    AMQP如何克服直接使用TCP发送消息时的困难 或者更具体地说 在发布 订阅场景中 在 AMQP 中 有一个代理 该代理接收消息 然后完成将消息路由到交换器和队列的困难部分 您还可以设置持久队列 即使客户端断开连接 也可以为客户端保存消息
  • 反向代理受 NTLM 保护的网站

    如何将请求代理到受 NTLM 保护的网站 例如团队基金会 and 共享点 我不断得到401 身份验证错误 根据这篇 Microsoft TechNet 文章 https www microsoft com technet prodtechn
  • 生产者/消费者的不同语言

    我想知道是否可以通过 AMQP 和 RabbitMQ 对生产者和消费者使用不同的语言 例如 Java 代表生产者 python php 代表消费者 或者反之亦然 是的 AMQP 与语言无关 这意味着只要您有可以连接到 AMQP 的客户端sa
  • RabbitMQ 等待消息超时

    我想向 RabbitMQ 服务器发送一条消息 然后等待回复消息 在 回复 队列上 当然 我不想永远等待 以防处理这些消息的应用程序出现故障 需要有一个超时 这听起来像是一项非常基本的任务 但我找不到方法来做到这一点 我现在在使用 Java

随机推荐

  • android Button按下及抬起监听事件

    首先我们在 布局中 xff0c 写入Button按钮 lt xml version 61 34 1 0 34 encoding 61 34 utf 8 34 gt lt LinearLayout xmlns android 61 34 ht
  • JZVIdeoPlayer(节操视频播放)

    比如jiecao的视频播放 依赖一个是视频 xff0c picasso 图片加载框架 compile 39 cn jzvd jiaozivideoplayer 6 0 0 39 compile 39 com squareup picasso
  • Android Apk编译的apk安装失败解决

    一 xff1a 如果直接拷贝到手机进行安装 提示安装失败 xff0c 解决有两种 第一 xff1a 在我们项目中的 gradle properties 文件中加入 xff0c 下面的那句 android injected testOnly
  • Android APP第三方支付流程

    手机APP 支付宝接入 1 开发前准备 xff1a 申请一个通过实名认证的企业支付宝账号 下载SDK开发包 提供APP apk以备审核 xff0c 审核通过后即可进行代码集成 2 流程 流程图 xff1a 流程解释 xff1a app携带支
  • Android介绍如何生成keystore 文件并使用

    cmd下 进入到jdk的bin目录 xff0c 这样的话 xff0c android keystore文件就会生成在这个目录下 签名的时候我们需要这个文件 C Program Files Java jdk1 7 0 01 bin gt ke
  • android代码APK混淆

    实际的产品研发中为了防止自己的劳动成果被别人窃取 xff0c 混淆代码能有效防止apk文件被反编译 xff0c 进而查看源代码 说来惭愧 xff0c 作为互联网创业公司的我们也确实对竞品Apk反编译研究过 xff0c 如果Apk混淆之后确实
  • android资源文件混淆

    前面一篇文章我们说过Apk的混淆 xff0c 除了源代码的混淆 xff0c 还有资源文件的混淆 微信推出的apk资源混淆方案 xff0c 该方案的具体原理课参见 xff1a 安装包立减1M 微信Android资源混淆打包工具 微信资源混淆工
  • WebView使用

    https www cnblogs com xunzhi p 6023190 html span class hljs keyword public span span class hljs class span class hljs ke
  • 最新研究:AI已可诊断50种眼疾,1.2秒内确认神经系统疾病

    本文由人工智能观察编译 译者 xff1a Sandy 近年来 xff0c 人工智能技术与医疗健康领域的融合不断加深 xff0c 且在科技巨头与资本巨头积极布局的努力下 xff0c 智能医疗正在不断取得新的突破 而根据 自然医学 xff08
  • stm32 fsmc 功能讲解

    LCD有如下控制线 xff1a CS xff1a Chip Select 片选 xff0c 低电平有效 RS xff1a Register Select 寄存器选择 WR xff1a Write 写信号 xff0c 低电平有效 RD xff
  • go语言基础之面向接口编程示例

    span class token keyword package span main span class token keyword import span span class token punctuation span span c
  • ZynqMP SOC 启动Linux遇到TF卡只读(RO)报错

    如果TF卡作为root启动Linux遇到如下错误 xff1a mmcblk0 mmc0 13ab SE128 115 GiB ro VFS Cannot open root device 34 mmcblk0p2 34 or unknown
  • mmc0: error -84 whilst initialising SD card

    玩zynqMP的板子上的SOC xff0c TF作为root启动petalinux系统 xff0c 碰到如下报错 xff1a error 84 whilst initialising SD card 查询Kernel代码中的sd c也没有看
  • .gradle文件夹下没有gradle.properties

    前言 可直接跳过此段到解决方法 前两天刚配置好Android的环境 xff0c 创建了一个Google的sample 但是在构建的过程中就出了问题 Unable to resolve dependency for 39 app 64 deb
  • eclipse编写web.xml中出现The word '...' is not correctly spelled

    为什么会这样呢 xff1f 因为eclipse中设置了拼写检查 xff0c 解决方法 window gt preferences gt 输入spelling xff0c 将右面的enable spelling checking复选框中的勾去
  • centos vsftpd安装

    1 安装vsftpd yum install vsftpd service vsftpd restart vi etc vsftpd vsftpd conf 配置见最下文 vi etc vsftpd vsftpd conf chroot l
  • 小米2013校园招聘笔试题

    题目 xff1a 一个数组里 xff0c 除了三个数是唯一出现的 xff0c 其余的都出现偶数个 xff0c 找出这三个数中的任一个 比如数组元素为 1 2 4 5 6 4 2 xff0c 只有1 5 6这三个数字是唯一出现的 xff0c
  • 自制Anki选择题模板(支持桌面版/移动版)

    复习面试知识偶然发现了一个小东西 anki xff0c 感觉挺好用就是模板有点少 xff0c 做选择题比较费劲 xff0c 网上找了几个终究不如我心意 xff0c 于是参考前人源码 xff0c 自己改编了一个看起来还不错的版本 这是很久以前
  • VMware Workstation 安装 CentOS 7 虚拟机

    安装步骤 VMware 创建CentOS虚拟机 Jack魏的博客 CSDN博客 https blog csdn net WeiHao0240 article details 100894672 VMware Workstation Pro
  • 基于 HAProxy + Keepalived 搭建 RabbitMQ 高可用集群

    RabbitMQ 集群 通常情况下 xff0c 在集群中我们把每一个服务称之为一个节点 xff0c 在 RabbitMQ 集群中 xff0c 节点类型可以分为两种 xff1a 内存节点 xff1a 元数据存放于内存中 为了重启后能同步数据