我是靠谱客的博主 花痴百合,最近开发中收集的这篇文章主要介绍HAProxy+Keepalived搭建RabbitMQ高可用集群一、简介二、准备工作二、单节点RabbitMQ服务安装步骤三、普通集群配置四、镜像集群配置五、RabbitMQ3.5.6+HAProxy+Keepalived搭建RabbitMQ高可用镜像模式集群六、Keepalived 存活自检测七、Keepalived的脑裂问题与解决八、Keepalived邮件通知配置九、RabbitMQ其他介绍,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 一、简介
  • 二、准备工作
    • 1、安装环境
    • 2、软件版本
    • 3、三台虚机
    • 4、集群命名
    • 5、配置hostname
      • 5.1、修改hostname
        • 5.1.1、修改172.22.40.104机器的hostname
        • 5.1.2、修改172.22.40.105机器的hostname
        • 5.1.3、修改172.22.40.106机器的hostname
  • 二、单节点RabbitMQ服务安装步骤
    • 1、安装工具包和常用命令
    • 2、安装Erlang
    • 3、解压Erlang
    • 4、进入Erlang解压目录
    • 5、Erlang配置安装
      • 5.1、检查编译环境并配置安装路径
      • 5.2、编译和安装
      • 5.3、设置Erlang环境变量
      • 5.4、添加如下文本
      • 5.5、保存并使环境变量立即生效
      • 5.6、验证是否安装成功
    • 6、安装RabbitMQ
      • 6.1、下载安装包
      • 6.2、解压RabbitMQ安装包
      • 6.3、进入RabbitMQ解压目录
      • 6.4、配置RabbitMQ的环境变量
      • 6.5、添加如下文本
      • 6.6、保存并使环境变量立即生效
      • 6.7、启动和设置用户管理插件
        • 6.7.1、后台启动RabbitMQ服务
        • 6.7.2、添加admin用户
        • 6.7.3、启用web后台管理插件
        • 6.7.4、启动和关闭
        • 6.7.5、查看端口
        • 6.7.6、管理界面访问测试
  • 三、普通集群配置
    • 1、准备好所有节点的RabbitMQ服务
    • 2、修改hosts配置文件
    • 2、查看hosts是否生效
    • 3、同步.erlang.cookie文件
      • 3.1、Erlang Cookie
      • 3.2、Erlang Cookie的位置
      • 3.3、Erlang Cookie的权限
      • 3.4、Erlang Cookie的同步
    • 4、创建集群
      • 4.1、将节点rabbit@rabbitmq-2加入到rabbit@rabbitmq-1的集群中
      • 4.2、将节点rabbit@rabbitmq-3加入到集群中
      • 4.3、设置集群名字
  • 四、镜像集群配置
    • 4.1、镜像集群
    • 4.2、测试镜像策略是否生效
  • 五、RabbitMQ3.5.6+HAProxy+Keepalived搭建RabbitMQ高可用镜像模式集群
    • 5.1、环境描述
    • 5.2、网络结构图
    • 5.3、安装高可用所需要的服务
      • 5.3.1、安装HAProxy
        • 5.3.1.1、配置HAProxy
        • 5.3.1.2、haproxy rsyslog日志配置
        • 5.3.1.3、重启日志服务+启动haproxy代理服务
        • 5.3.1.4、访问HAProxy监控统计界面
        • 5.3.1.5、访问RabbitMQ管理界面
      • 5.3.2、安装Keepalived
        • 5.3.2.1、安装相关命令
        • 5.3.2.2、 编写HAProxy检测脚本
      • 5.3.3、启动keepalived的服务
      • 5.3.4、测试vip是否可用
      • 5.3.5、测试vip飘移(主备切换)并验证短信和邮件通知
  • 六、Keepalived 存活自检测
    • 6.1、存活自检测脚本
    • 6.2、编写定时任务
  • 七、Keepalived的脑裂问题与解决
    • 7.1、什么是脑裂?
    • 7.2、keepalived脑裂产生的原因
    • 7.3、那么keepalived是如何解决或者防止脑裂问题的?
      • 7.3.1、首先介绍如何防止
      • 7.3.2、如何避免?
        • 7.3.2.1、keepalived非抢占配置
    • 7.4、Keepalived脑裂复现及非抢占模式避免测试
      • 7.4.1、最简单的复现步骤
      • 7.4.2、使用非抢占模式配置 Keepalived,再次测试脑裂
  • 八、Keepalived邮件通知配置
  • 九、RabbitMQ其他介绍

一、简介

本人经过长时间对 RabbitMQ 消息中间件服务的维护,整理了用HAProxy+Keepalived搭建RabbitMQ高可用镜像集群的操作流程,方便大家参考。

需要注意的是:Keepalived存在脑裂问题,本文也会带大家复现并解决脑裂的问题。

二、准备工作

1、安装环境

Centos-release-7-3

2、软件版本

软件版本
Erlang18.2
RabbitMQ3.5.6
keepalived1.3.5
haproxy1.5.18

Erlang和RabbitMQ版本关系如下:

RabbitMQErlang/OTP
3.8.16,3.8.17,3.8.18,3.8.1923.2~24.x
3.8.9,3.8.10,3.8.11,3.8.12,3.8.13,3.8.14,3.8.1522.3~23.x
3.8.4,3.8.5,3.8.6,3.8.7,3.8.821.3~23.x
3.7.15,3.7.16,3.7.17,3.7.1820.3~22.x
3.7.11,3.7.12,3.7.13,3.7.1420.3~21.x
3.7.7,3.7.8,3.7.9,3.7.1019.3~21.x
3.7.0,3.7.1,3.7.2,3.7.3,3.7.4,3.7.5,3.7.619.3~20.x

3、三台虚机

节点部署的服务节点类型
172.22.40.104RabbitMQ磁盘节点
172.22.40.105RabbitMQ磁盘节点
172.22.40.106RabbitMQ磁盘节点

4、集群命名

rabbitmq-group-1

5、配置hostname

RabbitMQ节点是由节点名称标识并根据节点名称存储数据。在集群中,节点使用节点名称相互识别和联系,节点名称由两部分:固定前缀rabbit@和hostname,如:rabbit@localhost。

5.1、修改hostname

节点hostname
172.22.40.104rabbitmq-1
172.22.40.105rabbitmq-2
172.22.40.106rabbitmq-3
#使用hostname命令设置hostname值
[root@localhost ~]# hostname yourHostname
#修改静态主机名
[root@localhost ~]# echo yourHostname > /etc/hostname
注意:此命令修改hostname可立即生效,但系统重启后失效。为了保证重启后依然有效,需要修改 /etc/sysconfig/network 配置文件:
[root@localhost ~]# vim /etc/sysconfig/network
输入以下内容:
	NETWORKING=yes
	NETWORKING_IPV6=yes
	HOSTNAME=yourHostname

#修改/etc/sysconfig/network需要重启机器才能生效
#也使用命令 sysctl kernel.hostname 使其立即生效
[root@localhost ~]# sysctl kernel.hostname=yourHostname

5.1.1、修改172.22.40.104机器的hostname

#修改 hostname
[root@localhost ~]# hostname rabbitmq-1

#查看当前hostname,看是否修改成功
[root@localhost ~]# hostname

#查看静态主机名
[root@localhost ~]# cat /etc/hostname

#修改静态主机名
[root@localhost ~]# echo rabbitmq-1 > /etc/hostname

#使hostname永久有效
[root@localhost ~]# vim /etc/sysconfig/network
输入:
	NETWORKING=yes
	NETWORKING_IPV6=yes
	HOSTNAME=rabbitmq-1

#使 /etc/sysconfig/network 配置中的hostname立即生效
[root@localhost ~]# sysctl kernel.hostname=rabbitmq-1

#修改完后,重新登录机器可以看到hostname修改成功
[root@rabbitmq-1 ~]#

5.1.2、修改172.22.40.105机器的hostname

同上

5.1.3、修改172.22.40.106机器的hostname

同上

二、单节点RabbitMQ服务安装步骤

1、安装工具包和常用命令

其实RabbitMQ只需要socat,因为我这里是新机器,索性一次性都安装了

yum groupinstall "Development Tools"
yum -y install wget make unzip zip gcc gcc-c++ kernel-devel m4 ncurses-devel openssl-devel gtk2-devel binutils-devel unixODBC-devel socat lrzsz wxWidgets-devel epel-release ncurses-devel logrotate

2、安装Erlang

wget http://erlang.org/download/otp_src_18.2.tar.gz

erlang 下载地址: http://www.rabbitmq.com/releases/erlang/

3、解压Erlang

tar -xzvf otp_src_18.2.tar.gz

4、进入Erlang解压目录

cd otp_src_18.2

5、Erlang配置安装

5.1、检查编译环境并配置安装路径

./configure --prefix=/usr/local/otp_src_18.2 --without-javac

5.2、编译和安装

#从makefile中读取指令,执行源码编译命令和安装命令
make && make install

5.3、设置Erlang环境变量

vim /etc/profile

5.4、添加如下文本

#set erlang environment
export PATH=$PATH:/usr/local/otp_src_18.2/bin

5.5、保存并使环境变量立即生效

source /etc/profile

5.6、验证是否安装成功

erl

6、安装RabbitMQ

6.1、下载安装包

https://github.com/rabbitmq/rabbitmq-server/releases/tag/rabbitmq_v3_5_6/

下载:rabbitmq-server-generic-unix-3.5.6.tar.gz
下载后把包上传到服务器 /usr/local 目录下

6.2、解压RabbitMQ安装包

tar -xzvf rabbitmq-server-generic-unix-3.5.6.tar.gz 

6.3、进入RabbitMQ解压目录

cd rabbitmq_server-3.5.6

6.4、配置RabbitMQ的环境变量

vim /etc/profile

6.5、添加如下文本

#rabbitMQ配置
export PATH=$PATH:/usr/local/rabbitmq_server-3.5.6/sbin

6.6、保存并使环境变量立即生效

source /etc/profile

6.7、启动和设置用户管理插件

cd /usr/local/rabbitmq_server-3.5.6/sbin

6.7.1、后台启动RabbitMQ服务

./rabbitmq-server -detached

提示:这个后台启动命令,执行的时候会报 Warning: PID file not written; -detached was passed.
官方解释后台启动有此 bug,不影响服务正常启动使用,忽略即可。

6.7.2、添加admin用户

#因为guest用户只能在本机访问(只能通过localhost登陆使用),添加一个admin用户,密码设置为:963741852
./rabbitmqctl add_user admin 963741852
#设置admin为超级管理员
./rabbitmqctl set_user_tags admin administrator
#为admin账号添加所有的权限
./rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
#RabbitMQ默认账户和密码为 guest/guest,我们修改guest用户密码
./rabbitmqctl change_password guest 852963741
#查看当前的用户列表
./rabbitmqctl list_users
 #如果想要删除一个用户
./rabbitmqctl delete_user yourUserName

6.7.3、启用web后台管理插件

./rabbitmq-plugins enable rabbitmq_management
./rabbitmq-plugins enable rabbitmq_shovel
./rabbitmq-plugins enable rabbitmq_shovel_management

#对应的禁用web后台管理插件
./rabbitmq-plugins disable rabbitmq_management
./rabbitmq-plugins disable rabbitmq_shovel
./rabbitmq-plugins disable rabbitmq_shovel_management

6.7.4、启动和关闭

1)直接启动模式:如果你关闭窗口或者需要在该窗口使用其他命令时应用就会停止
./rabbitmq-server 			//启动
./rabbitmq-server restart 	//重启
./rabbitmq-server stop 		//停止
./rabbitmq-server status 	//查看状态

2)rabbitmq以应用方式后台启动
./rabbitmq-server -detached //rabbitmq分别启动节点和应用,不会生成pid_file文件
./rabbitmqctl status 		//查看运行状态
./rabbitmqctl start_app 	//应用启动,此命令典型的用途是在执行了其他管理操作之后,重新启动之前停止的 RabbitMQ 应用,比如reset
./rabbitmqctl stop_app 		//将rabbitmq服务应用关闭,但是Erlang虚拟机还是处于运行状态
./rabbitmqctl stop 			//同时关闭应用和节点

6.7.5、查看端口

#15672是HTTP API客户端、web管理界面使用,25672用于broker节点间通信,5672是AMQP使用的端口
netstat -lnp |grep beam

6.7.6、管理界面访问测试

http://172.22.40.104:15672

三、普通集群配置

1、准备好所有节点的RabbitMQ服务

同上面单节点RabbitMQ服务安装的步骤,把172.22.40.105、172.22.40.106这两台机器上也安装好RabbitMQ服务。

2、修改hosts配置文件

绑定ip和hostname的映射关系,便于RabbitMQ节点间进行DNS解析和通信

[root@rabbitmq-1 ~]# cat /etc/hosts
[root@rabbitmq-1 ~]# vim /etc/hosts

三台机器的hosts文件中都添加如下文本:
172.22.40.104 rabbitmq-1
172.22.40.105 rabbitmq-2
172.22.40.106 rabbitmq-3

2、查看hosts是否生效

#在任意一台机器上ping这三个hostname,能正确解析出对应ip即成功
[root@rabbitmq-1 ~]# ping rabbitmq-1 

3、同步.erlang.cookie文件

3.1、Erlang Cookie

RabbitMQ节点是使用cookie来确定它们是否被允许相互通信的(erlang集群是通过这个cookie进行通信认证),为了让节点间能够通信,它们必须具有相同的共享秘密,称为:Erlang Cookie。
所以必须确保集群中的每个RabbitMQ节点都使用相同的cookie值。

3.2、Erlang Cookie的位置

Erlang Cookie的位置通常在:$HOME/.erlang.cookie
所以要想知道Erlang Cookie位置,首先要取得RabbitMQ启动日志里面的home dir的根路径:
#RabbitMQ日志所在目录:/usr/local/rabbitmq_server-3.5.6/var/log/rabbitmq
[root@rabbitmq-1 ~]# cd /usr/local/rabbitmq_server-3.5.6/var/log/rabbitmq
[root@rabbitmq-1 rabbitmq]# cat rabbit@rabbitmq-1.log | grep home
home dir       : /root
home dir       : /root
可知,RabbitMQ的$HOME目录为:/root

3.3、Erlang Cookie的权限

[root@rabbitmq-1 rabbitmq]# cd ~
[root@rabbitmq-1 ~]# ls -la // 可以看到一个 .erlang.cookie 文件
[root@rabbitmq-1 ~]# chmod 400 /root/.erlang.cookie // 修改.erlang.cookie的权限为只读
#如果需要,请把.erlang.cookie文件的拥有者改为指定的rabbitmq用户或组
#[root@rabbitmq-1 ~]# chown -R rabbitmq:rabbitmq .erlang.cookie
[root@rabbitmq-1 ~]# cat .erlang.cookie // 查看cookie的值

注意:.erlang.cookie 文件的权限必须是400,不然存在节点之间无法通信的风险。
扩展:
	chmod权限的三个数字:
	第一个数字表示文件所有者的权限
	第二个数字表示与文件所有者同属一个用户组的其他用户的权限
	第三个数字表示其它用户组的权限
	权限分为三种:读(r=4),写(w=2),执行(x=1),无(-=0)。
	综合起来还有:只读(r=4)、可读可执行(rx=5=4+1)、可读可写(rw=6=4+2)、可读可写可执行(rwx=7=4+2+1)

	所以:
	chmod 400 file // 所有人只读
	chmod 600 file // 设置拥有者可读写及执行
	chmod 777 file // 所有人可以读写及执行

3.4、Erlang Cookie的同步

保持三台机器的.erlang.cookie值一致
在172.22.40.105机器执行:
[root@rabbitmq-2 ~]# scp root@172.22.40.104:/root/.erlang.cookie /root/
[root@rabbitmq-2 ~]# chmod 400 /root/.erlang.cookie

在172.22.40.106机器执行:
[root@rabbitmq-3 ~]# scp root@172.22.40.104:/root/.erlang.cookie /root/
[root@rabbitmq-3 ~]# chmod 400 /root/.erlang.cookie

注意:.erlang.cookie 文件同步复制完成后,须逐个重启节点服务。

4、创建集群

为了使三个节点连接到一起组成一个集群,我们需要把另外两个节点(rabbit@rabbitmq-2和rabbit@rabbitmq-3)加入到第一个节点(rabbit@rabbitmq-1)。在此之前,必须重新设置两个新加入的成员节点。

4.1、将节点rabbit@rabbitmq-2加入到rabbit@rabbitmq-1的集群中

#在rabbit@rabbitmq-2[root@rabbitmq-2 ~]# cd /usr/local/rabbitmq_server-3.5.6/sbin/
[root@rabbitmq-2 sbin]# ./rabbitmqctl stop_app
Stopping node 'rabbit@rabbitmq-2' ...

[root@rabbitmq-2 sbin]# ./rabbitmqctl reset
Resetting node 'rabbit@rabbitmq-2' ...

#加入集群时指定节点类型,--ram 指定内存节点类型,不指定默认为磁盘节点类型
[root@rabbitmq-2 sbin]# ./rabbitmqctl join_cluster rabbit@rabbitmq-1
Clustering node 'rabbit@rabbitmq-2' with 'rabbit@rabbitmq-1' ...

[root@rabbitmq-2 sbin]# ./rabbitmqctl start_app
Starting node 'rabbit@rabbitmq-2' ...

[root@rabbitmq-2 sbin]# ./rabbitmqctl cluster_status
Cluster status of node 'rabbit@rabbitmq-2' ...
[{nodes,[{disc,['rabbit@rabbitmq-1']},{disc,['rabbit@rabbitmq-2']}]},
 {running_nodes,['rabbit@rabbitmq-1','rabbit@rabbitmq-2']},
 {cluster_name,<<"rabbit@rabbitmq-1">>},
 {partitions,[]}]

4.2、将节点rabbit@rabbitmq-3加入到集群中

这次我们将rabbit@rabbitmq-3节点集群到rabbit@rabbitmq-2节点来证明新节点加入集群时跟选择集群的节点无关紧要,只须提供一个在线节点。

#在rabbit@rabbitmq-3[root@rabbitmq-3 ~]# cd /usr/local/rabbitmq_server-3.5.6/sbin/
[root@rabbitmq-3 sbin]# ./rabbitmqctl stop_app
Stopping node 'rabbit@rabbitmq-3' ...

[root@rabbitmq-3 sbin]# ./rabbitmqctl reset
Resetting node 'rabbit@rabbitmq-3' ...

[root@rabbitmq-3 sbin]# ./rabbitmqctl join_cluster rabbit@rabbitmq-2
Clustering node 'rabbit@rabbitmq-3' with 'rabbit@rabbitmq-2' ...

[root@rabbitmq-3 sbin]# ./rabbitmqctl start_app
Starting node 'rabbit@rabbitmq-3' ...

[root@rabbitmq-3 sbin]# ./rabbitmqctl cluster_status
Cluster status of node 'rabbit@rabbitmq-3' ...
[{nodes,[{disc,['rabbit@rabbitmq-1']},
         {disc,['rabbit@rabbitmq-3','rabbit@rabbitmq-2']}]},
 {running_nodes,['rabbit@rabbitmq-2','rabbit@rabbitmq-1','rabbit@rabbitmq-3']},
 {cluster_name,<<"rabbit@rabbitmq-1">>},
 {partitions,[]}]

4.3、设置集群名字

#在任意一台节点机器上查看集群状态
[root@rabbitmq-1 sbin]# ./rabbitmqctl cluster_status
可知,集群的名字为:rabbit@rabbitmq-1

#在任意一台节点机器上执行修改集群名字的命令
[root@rabbitmq-1 sbin]# ./rabbitmqctl set_cluster_name rabbitmq-group-1
Setting cluster name to rabbitmq-group-1 ...

再次查看集群状态可知,集群的名字已变更为:rabbitmq-group-1

在这里插入图片描述

四、镜像集群配置

上面配置的普通集群为RabbitMQ默认集群模式,但并不保证队列的高可用性,尽管队列名、交换机、绑定关系这些元数据可以在集群节点间相互复制,但是队列中的内容不会被复制,虽然该模式解决一部分节点压力,但队列节点宕机将直接导致该队列无法使用,只能等待重启,所以要想在队列节点宕机或故障的时候也能正常使用,就要复制队列的内容到集群里的每个节点,需要创建镜像队列。
在这里插入图片描述

4.1、镜像集群

在普通集群的基础上,创建镜像策略,如下,即可实现集群之间镜像复制:

在任意一个节点上创建镜像策略:
Name:HA
Pattern:.*	// 匹配的规则,如果是匹配所有的队列,那就是 ^ 或者 .*
Apply to:Exchanges and queues
Priority:
Definition: // 使用ha-mode模式中的all,也就是同步所有匹配的队列
	ha-mode=all
	ha-sync-mode=automatic // 设置自动同步集群节点间的镜像

在这里插入图片描述

使用Rabbit镜像功能,需要基于rabbitmq策略来实现,策略是用来控制和修改群集内的队列行为和Exchange行为。

当然,也可以用命令创建镜像策略:
设置镜像队列,在三台机器上分别执行:
./rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'

这行命令在vhost名称为"/"创建了一个策略,策略名称为ha-all,策略模式为 all 即复制到所有节点,包含新增节点,策略正则表达式为 “^” 表示匹配所有队列名称。

#命令行创建镜像策略示例:以 order 开头的队列消息都会自动同步到集群各个节点
rabbitmqctl set_policy ha-all "^order." '{"ha-mode":"all","ha-sync-mode":"automatic"}'

注意:一旦创建了镜像,集群节点中会自动创建aliveness-test这个队列,用于存活检测:
curl -i -u guest:852963741 http://localhost:15672/api/vhosts/
curl -i -u guest:852963741 http://localhost:15672/api/aliveness-test/%2F

4.2、测试镜像策略是否生效

在这里插入图片描述
当往集群一个节点发消息时,其他节点会自动同步数据;




五、RabbitMQ3.5.6+HAProxy+Keepalived搭建RabbitMQ高可用镜像模式集群

5.1、环境描述

节点 ip主机名当前节点上部署的服务
172.22.40.104rabbitmq-1rabbitmq服务、HAProxy、Keepalived(主)
172.22.40.105rabbitmq-2rabbitmq服务、HAProxy、Keepalived(备)
172.22.40.106rabbitmq-3rabbitmq服务、vip
172.22.40.1虚拟 ip(确保ip不存在)VIP

注意:
1、由于机器不足的原因,我这里是将haproxy、keepalived 都部署在了rabbitmq集群所在的节点上,但如果生产环境中还是建议单独拿出两台机器做haproxy跟keepalived。
2、linux 服务器需要关闭:selinux、firewalld
3、linux 服务器必须开启ip转发功能:net.ipv4.ip_forward = 1
否则haproxy启动可能会报 类似的错:Starting proxy haproxy_stats: cannot bind socket [0.0.0.0:80]
····································································································
扩展知识:
一、linux 开启 IP 转发功能
linux发行版默认情况下是不开启ip转发功能的。因为大部分用不到。但是,如果我们想架设一个linux路由或者vpn服务我们就需要开启该服务了。

1)查看是否开启转发
cat /proc/sys/net/ipv4/ip_forward
#返回1代表IP已开启,0 未开启
2)临时开启
echo 1 > /proc/sys/net/ipv4/ip_forward
3)永久开启
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
4)立即生效
sysctl -p /etc/sysctl.conf &

二、selinux是什么?有啥用?如何开启和关闭?
1)它叫做“安全增强型Linux(Security-Enhanced Linux)”,简称 SELinux,它是 Linux 的一个安全子系统。
2)其主要作用就是最大限度地减小系统中服务进程可访问的资源(根据的是最小权限原则)。避免权限过大的角色给系统带来灾难性的结果。
3)如何开启关闭:

#查看selinux状态
[root@rabbitmq-1 ~]# getenforce
Disabled
#临时关闭selinux
[root@rabbitmq-1 ~]# setenforce 0
#永久关闭selinux
[root@rabbitmq-1]# vim /etc/selinux/config
将 SELINUX=enforcing 改为 SELINUX=disabled

三、firewalld服务?
可参考:https://blog.csdn.net/weixin_44192363/article/details/116810814

5.2、网络结构图

在这里插入图片描述
或者
在这里插入图片描述

5.3、安装高可用所需要的服务

5.3.1、安装HAProxy

我们用haproxy做负载均衡,在172.22.40.104、172.22.40.105 节点上安装haproxy服务。

#安装命令。其中 -y 的含义:当安装过程提示选择全部为"yes"。
yum install -y haproxy

5.3.1.1、配置HAProxy

#1)首先备份原始配置(仅仅是备份下方便查阅其他配置项,不用的话可以直接改)
cp /etc/haproxy/haproxy.cfg{,.bak}

#2)编辑配置文件,配置文件具体内容如下
vim /etc/haproxy/haproxy.cfg  

配置文件具体内容(172.22.40.104、172.22.40.105 节点配置相同,复制即可)

#----------------------------------------------------
# Global settings
#----------------------------------------------------
global
    log         127.0.0.1 local2 info #定义全局的syslog服务器。日志服务器需要开启UDP协议,最多可以定义两个。基于syslog记录日志到指定设备,级别有(err、warning、info、debug)
    chroot      /var/lib/haproxy #锁定haproxy的运行目录,把haproxy的进程禁锢在一个文件夹内
    pidfile     /var/run/haproxy.pid #指定haproxy的pid文件存放路径,启动进程的用户必须有权限访问此文件。要和service指定的pid路径一样
    maxconn     100000 #每个haproxy进程的最大并发连接数,默认4000,可以是100000,还可以更大:一百万
    maxconnrate 4000 #每个进程每秒创建的最大连接数量,控制瞬间并发
    user        haproxy #默认用户
    group       haproxy #默认组
    daemon #以后台守护进程的方式运行
    stats socket /var/lib/haproxy/stats #创建监控所用的套接字目录
#--------------------------------------------------
# defaults settings
#--------------------------------------------------
defaults
    mode		http #默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK。后面listen的优先级比默认高,可以单独设置。
    log			global
    option		dontlognull #启用该项,日志中将不会记录空连接。所谓空连接就是在上游的负载均衡器
    option		http-server-close #每次请求完毕后主动关闭http通道
    option		http-keep-alive #开启与客户端的会话保持
    option		redispatch #serverId对应的服务器挂掉后,强制定向到其他健康的服务器,重新派发。
    retries		3 #3次连接失败就认为服务不可用
    timeout http-request    10s
    timeout queue           1m
    timeout connect         30s #客户端请求从haproxy到后端server最长连接等待时间(TCP连接之前),默认单位ms
    timeout client          2m #设置haproxy与客户端的最长非活动时间,默认单位ms,建议和timeout server相同
    timeout server          2m #客户端请求从haproxy到后端服务端的请求处理超时时长(TCP连接之后),默认单位ms,如果超时,会出现502错误,此值建议设置较大些,访止502错误。
    timeout http-keep-alive 30s #session会话保持超时时间,此时间段内会转发到相同的后端服务器
    timeout check           10s #对后端服务器的默认检测超时时间
    maxconn                 10000 #最大连接数
#--------------------------------------------------
# haproxy监控统计界面 settings
#--------------------------------------------------
listen admin_stats
        stats   enable #自动开启
        bind    0.0.0.0:9188 #访问检测界面入口绑定的端口跟地址
        mode    http #http的七层模型
        option  httplog #采用http日志格式
        log     global
        maxconn 10 #默认最大连接数
        stats refresh 30s #统计页面自动刷新时间
        stats uri /admin_stats #统计页面url,设置haproxy监控地址为http://localhost:9188/admin_stats
        stats auth admin:dhgate20221012  #设置监控页面的用户和密码认证:admin:dhgate20221012,可以设置多个用户名
        stats hide-version #隐藏统计页面上HAProxy的版本信息
        stats realm (Haproxy statistic platform) #统计页面密码框上提示文本
        stats admin if TRUE #设置手工启动/禁用,后端服务器(haproxy-1.4.9以后版本)
#--------------------------------------------------
# 监听rabbimq_server settings
#--------------------------------------------------
listen rabbitmq_server
        bind 0.0.0.0:55672 #指定HAProxy的监听地址,可以是IPV4或IPV6,可以同时监听多个IP或端口。MQ连接端口,避免跟5672端口冲突,将rabbitmq的5672端口映射为55672端口
        mode tcp #指定负载协议类型
        log global
        balance roundrobin #balance roundrobin 负载轮询,balance source 保存session值,支持static-rr,leastconn,first,uri等参数。
        server  rabbitmq1 172.22.40.104:5672 maxconn 4000 weight 1 check inter 5s rise 2 fall 2
        server  rabbitmq2 172.22.40.105:5672 maxconn 4000 weight 1 check inter 5s rise 2 fall 2
        server  rabbitmq3 172.22.40.106:5672 maxconn 4000 weight 1 check inter 5s rise 2 fall 2
        #rise 2是2次正确认为服务器可用
        #fall 2是2次失败认为服务器不可用
        #check inter 5s 表示检查心跳频率
        #weight代表权重
        #maxconn 4000 当前服务器支持的最大并发连接数,超出此值的连接将被放置于请求队列中
#--------------------------------------------------
# 监听rabbitmq_web settings
#--------------------------------------------------
listen rabbitmq_web
        bind 0.0.0.0:35672 #将rabbitmq的15672端口映射为35672端口
        mode http
        log global
        option httplog
        option httpclose
        balance roundrobin
        server  rabbitmq1 172.22.40.104:15672 maxconn 2000 weight 1 check inter 5s rise 2 fall 2
        server  rabbitmq2 172.22.40.105:15672 maxconn 2000 weight 1 check inter 5s rise 2 fall 2
        server  rabbitmq3 172.22.40.106:15672 maxconn 2000 weight 1 check inter 5s rise 2 fall 2
#--------------------------------------------------

5.3.1.2、haproxy rsyslog日志配置

vim /etc/rsyslog.conf

#在文件的最后一行,加上:
local2.* /var/log/haproxy/rabbitmq.log

5.3.1.3、重启日志服务+启动haproxy代理服务

#重启日志服务
mkdir -p /var/log/haproxy && systemctl restart rsyslog.service

#启动haproxy。其中 -f 代表指定配置文件的路径。
haproxy -f /etc/haproxy/haproxy.cfg

#重新启动haproxy
haproxy -f /etc/haproxy/haproxy.cfg -st `cat /var/run/haproxy.pid`

#停止haproxy
kill -9 `cat /var/run/haproxy.pid`

#查看haproxy启动的端口
ss -nplt | grep haproxy

无报错即为启动成功,如有报错可查看系统日志 /var/log/message 中详细错误信息。

用同样的方法在 172.22.40.105 节点上安装haproxy,配置是相同的。

5.3.1.4、访问HAProxy监控统计界面

http://172.22.40.104:9188/admin_stats
http://172.22.40.105:9188/admin_stats

这两个能正常访问HAProxy监控界面,用设定的amdin/dhgate20221012登录:
在这里插入图片描述

5.3.1.5、访问RabbitMQ管理界面

http://172.22.40.104:35672/#/
http://172.22.40.105:35672/#/

这两个都能正常访问RabbitMQ管理界面:
在这里插入图片描述

5.3.2、安装Keepalived

用keepalived做主备,避免单点问题、实现高可用。在172.22.40.104(主)、172.22.40.105(备) 节点上分别安装Keepalived。

5.3.2.1、安装相关命令

#安装
yum install -y keepalived
#备份原有配置
cp /etc/keepalived/keepalived.conf{,.bak}
#配置Keepalived
vim /etc/keepalived/keepalived.conf

172.22.40.104节点为master,配置内容:

! Configuration File for keepalived

#keepalived全局配置
global_defs {
    #keepalived检测到故障主备切换时发送邮件通知配置项。
    #这里我直接改成了调邮件和短信服务接口,没有使用keepalived的notify功能。
    #短信和邮件接口配置在/etc/keepalived/haproxy_check.sh脚本里。
    
    #每个keepalived节点的唯一标识,不能与备机相同。
    router_id keepalived_master_172-22-40-104
}

#检测HAProxy脚本
vrrp_script check_haproxy {
   script "/etc/keepalived/haproxy_check.sh" #脚本所在的目录
   interval 10 #检测 haproxy 心跳频率:每隔10秒检测一次
   weight 2 #权重
}

#虚拟路由器配置
vrrp_instance haproxy {
    state MASTER #设置虚拟路由器状态为MASTER,表示为主。
    interface ens192 #绑定当前虚拟路由器所使用的物理网卡,如eth0、bond0等,可通过ifconfig获得。
    virtual_router_id 51 #每个虚拟路由器的唯一标识。同属一个虚拟路由器的多个keepalived节点必须相同,务必要确保在同一网络中此值唯一。
    priority 100 #当前物理节点在此虚拟路由器中的优先级,值越大优先级越高。注意:主机的优先权要比备机高。
    advert_int 1 #心跳检查频率,单位:秒。
    
    #认证机制
    authentication {
        auth_type PASS #认证类型
        auth_pass 1111 #秘钥,同一虚拟路由器的多个keepalived节点auth_pass值必须保持一致
    }

    #虚拟路由器的VIP,不指定网卡时默认添加在eth0上。在添加VIP地址时,需确保将要使用的VIP不存在,避免冲突。
    virtual_ipaddress {
        172.22.40.1 #对外开放的虚拟ip
    }

    #调用检测HAProxy的脚本
    track_script {
        check_haproxy
    }
}

172.22.40.105节点为backup,配置内容:

! Configuration File for keepalived

#keepalived全局配置
global_defs {
    #keepalived检测到故障主备切换时发送邮件通知配置项。
    #这里我直接改成了调邮件和短信服务接口,没有使用keepalived的notify功能。
    #短信和邮件接口配置在/etc/keepalived/haproxy_check.sh脚本里。
    
    #每个keepalived节点的唯一标识,不能与备机相同。
    router_id keepalived_backup_172-22-40-105
}

#检测HAProxy脚本
vrrp_script check_haproxy {
   script "/etc/keepalived/haproxy_check.sh" #脚本所在的目录
   interval 10 #检测 haproxy 心跳频率:每隔10秒检测一次
   weight 2 #权重
}

#虚拟路由器配置
vrrp_instance haproxy {
    state BACKUP #设置虚拟路由器状态为BACKUP,表示为备。
    interface ens192 #绑定当前虚拟路由器所使用的物理网卡,如eth0、bond0等,可通过ifconfig获得。
    virtual_router_id 51 #每个虚拟路由器的唯一标识。同属一个虚拟路由器的多个keepalived节点必须相同,务必要确保在同一网络中此值唯一。
    priority  80 #当前物理节点在此虚拟路由器中的优先级,值越大优先级越高。注意:主机的优先权要比备机高。
    advert_int 1 #心跳检查频率,单位:秒。
    
    #认证机制
    authentication {
        auth_type PASS #认证类型
        auth_pass 1111 #秘钥,同一虚拟路由器的多个keepalived节点auth_pass值必须保持一致
    }

    #虚拟路由器的VIP,不指定网卡时默认添加在eth0上。在添加VIP地址时,需确保将要使用的VIP不存在,避免冲突。
    virtual_ipaddress {
        172.22.40.1 #对外开放的虚拟ip
    }

    #调用检测HAProxy的脚本
    track_script {
        check_haproxy
    }
}

详细的keepalived配置可参考:https://blog.51cto.com/johnnyfang/5419017

5.3.2.2、 编写HAProxy检测脚本

接着,我们需要编写脚本:haproxy_check.sh
脚本作用:检测haproxy服务,如果haproxy服务挂了则先尝试自动重启haproxy服务;如果重启不成功, 则关闭Keepalived服务并切换到backup。

haproxy_check.sh检测脚本内容:

#!/bin/bash
#haproxy存活检测脚本
#当发现haproxy服务挂掉时,先自动重启HAProxy的服务,如果启动不成功则关闭当前节点的Keepalived服务,并将虚拟vip飘到备用节点上。

#-----------全局变量------------start
#本机ip
localIP=`ip a|grep inet|grep global|grep brd|head -n 1|awk '{printf $2}'|cut -d "/" -f1`
#backup节点ip
backupIP="172.22.40.105"

#邮件联系人
mailTo="yuanjiabo@xxx.com"
#短信联系人
phoneTo="1342621xxxx"

#邮件主题
mailsubject="队列集群高可用之Keepalived主备切换通知(vip floating)"
mailsubjectForHAProxyUp="队列集群高可用之HAProxy服务挂掉通知"
#邮件内容
nodeList="172.22.40.104、172.22.40.105、172.22.40.106"
mailbody="队列集群(集群节点:${nodeList})高可用keepalived vrrp transition, 虚拟VIP地址切换至:${backupIP},切换前的地址:${localIP}"
#短信内容
messagebody="检测到节点${localIP}的HAProxy服务挂掉,并尝试重启失败,停掉此节点上的keepalived服务,虚拟vip将floating到backup节点:${backupIP}"
messageForHAProxyUp="检测到节点${localIP}的HAProxy服务挂掉,正在尝试重启中...重启成功!"
#-----------全局变量------------end

#haproxy服务存活检测
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ];then
    #记录日志
    echo "检测到节点${localIP}的HAProxy服务挂掉,正在尝试重启中..." >> /etc/keepalived/keepalived_master2backup.log
    #重启haproxy服务
    haproxy -f /etc/haproxy/haproxy.cfg

    sleep 2s

    #haproxy自动重启成功,邮件+短信通知
    if [ $(ps -C haproxy --no-header | wc -l) -eq 1 ];then
        echo "检测到节点${localIP}的HAProxy服务挂掉,正在尝试重启中...重启成功!" >> /etc/keepalived/keepalived_master2backup.log
        #发邮件
        curl "http://172.21.200.247/message.php?item=mail&mailto=${mailTo}&subject=${mailsubjectForHAProxyUp}&msg=${messageForHAProxyUp}"
        #发短信
        curl "http://172.21.200.247/message.php?phone=${phoneTo}&msg=${messageForHAProxyUp}"
    fi
fi

#这里最好休眠2s等待haproxy启动成功,不然下面的判断有可能还会出现找不到haproxy服务进程的情况
#注意:这个sleep时间一定要比keepalived.conf配置里"检测 haproxy 心跳频率:interval  10"设置的时间要短,否则将卡在sleep这!
sleep 2s

#自动重启不成功,进行vip切换操作,邮件+短信通知
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ];then
    echo "检测到节点${localIP}的HAProxy服务挂掉,尝试重启失败,停掉此节点上的keepalived服务,虚拟vip将飘到backup节点:${backupIP}" >> /etc/keepalived/keepalived_master2backup.log

    #发邮件
    curl "http://邮件服务ip:port/message.php?item=mail&mailto=${mailTo}&subject=${mailsubject}&msg=${mailbody}"

    #发短信
    curl "http://短信服务ip:port/message.php?phone=${phoneTo}&msg=${messagebody}"

    service keepalived stop
fi

注意:此脚本同样需要复制到 172.22.40.105 节点上。

5.3.3、启动keepalived的服务

启动顺序:先启动master节点服务,再启动backup节点的服务。

#启动keepalived服务
service keepalived start

#查看keepalived状态
[root@rabbitmq-1 keepalived]# service keepalived status
Redirecting to /bin/systemctl status  keepalived.service
● keepalived.service - LVS and VRRP High Availability Monitor
   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)
   Active: active (running) since Thu 2022-10-13 15:58:35 CST; 8min ago
  Process: 19704 ExecStart=/usr/sbin/keepalived 
  
#查看keepalived启动日志:
journalctl -xe

#查看keepalived日志
tail -f  /var/log/messages

#停掉keepalived服务
service keepalived stop
  1. 在master上查看主机ip信息:
    在这里插入图片描述
    在这里插入图片描述
    可知绑定在ens192上的vip正常出现在master节点上,且主机 ip 多出了一个 172.22.40.1(配置文件中默认添加的虚拟VIP地址),而且也能ping通。

  2. 查看backup( 172.22.40.105)上的ip信息则没有此虚拟ip:
    在这里插入图片描述

5.3.4、测试vip是否可用

  1. 用VIP访问 RabbitMQ 管理平台:
    http://172.22.40.1:35672/#/
    在这里插入图片描述
  2. 用VIP访问HAProxy监控统计平台
    http://172.22.40.1:9188/admin_stats#
    在这里插入图片描述

5.3.5、测试vip飘移(主备切换)并验证短信和邮件通知

#启动 haproxy 服务
haproxy -f /etc/haproxy/haproxy.cfg
#停止 kaproxy 服务
kill -9 `cat /var/run/haproxy.pid`
#重新启动 haproxy 服务
haproxy -f /etc/haproxy/haproxy.cfg -st `cat /var/run/haproxy.pid`
#查看 haproxy 服务状态
ss -nplt | grep haproxy
#启动 keepalived 服务
service keepalived start
#查看 keepalived 服务状态
service keepalived status
#停止 keepalived 服务
service keepalived stop
  1. 关闭 master 节点(172.22.40.104) 的 haproxy 服务:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

此时, keepalived 每隔 10s 触发一次的haproxy心跳检测脚本haproxy_check.sh里自动恢复了 master 节点的 haproxy 服务。

虚拟 ip 没有飘到 backup 节点:在这里插入图片描述

  1. 模拟 master 节点的 haproxy 服务无法自动恢复时:
    在这里插入图片描述
    再次 kill 掉 master 节点的 haproxy 服务:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

结论:虚拟 ip 能在主备上自动切换,切换后 vip 自动从 master 上飘到 backup 上。并且切换动作触发时能收到邮件和短信通知!

  1. 飘移后继续测试vip是否可用:
    http://172.22.40.1:9188/admin_stats
    http://172.22.40.1:35672/#/

结论:用 vip 访问 HAProxy 监控统计平台和RabbitMQ管理平台,依然能访问成功!

  1. 恢复 master,看看 vip 能否飘回来
    在这里插入图片描述
    在这里插入图片描述

结论:当 master 节点恢复后,vip 自动飘回 master 节点!

六、Keepalived 存活自检测

新建一个定时任务,通过周期性触发执行 Keepalived 服务存活检测的脚本,达到实现监控 Keepalived 服务的目的。

6.1、存活自检测脚本

keepalived_is_ok.sh

#!/bin/bash
#keepalived服务自身存活检测脚本,定时任务周期执行该脚本进行 ke 存活的检测,当自身挂了之后发邮件和短信通知管理员。

#让本地变量生效,这行一定要加
source /etc/profile

#-----------全局变量------------start
#本机ip
localIP=`ip a|grep inet|grep global|grep brd|head -n 1|awk '{printf $2}'|cut -d "/" -f1`

#邮件联系人
mailTo="yuanjiabo@xxx.com"

#短信联系人
phoneTo="1342621xxxx"

#邮件主题
mailsubjectForKeepalived="队列集群高可用之Keepalived服务异常和恢复通知"

#短信内容
messageForKeepalivedDown="检测到节点${localIP}上的Keepalived服务挂掉,正在尝试重启中......"
messageForKeepalivedUP="检测到节点${localIP}上的Keepalived服务挂掉,正在尝试重启中......重启成功!请尽快登录机器检查服务状态!"
#-----------全局变量------------end

#Keepalived服务存活检测
#ps -ef | grep keepalived | grep -v grep | awk '{print$2}'
if [ $(ps -C keepalived --no-header | wc -l) -eq 0 ];then
    #服务宕机提醒邮件
    curl "http://172.21.200.247/message.php?item=mail&mailto=${mailTo}&subject=${mailsubjectForKeepalived}&msg=${messageForKeepalivedDown}"
    #服务宕机提醒短信
    curl "http://172.21.200.247/message.php?phone=${phoneTo}&msg=${messageForKeepalivedDown}"

    #Keepalived服务宕机,重启Keepalived服务
    service keepalived start

    #休眠5s,等待服务起来
    sleep 5s

    if [ $(ps -C keepalived --no-header | wc -l) -eq 3 ];then
        #服务恢复提醒邮件
        curl "http://172.21.200.247/message.php?item=mail&mailto=${mailTo}&subject=${mailsubjectForKeepalived}&msg=${messageForKeepalivedUP}"
        #服务恢复提醒短信
        curl "http://172.21.200.247/message.php?phone=${phoneTo}&msg=${messageForKeepalivedUP}"
    fi
fi

6.2、编写定时任务

1、检查 crontab 服务是否开启:
systemctl status crond

2、新增或编辑定时任务
crontab -e

#每5分钟执行一次Keepalived服务存活检测脚本
*/5 * * * * /etc/keepalived/keepalived_is_ok.sh >/dev/null 2>&1

3、重启crontab服务(不生效的话再重启,一般都会立即生效)
systemctl stop crond
systemctl start crond

4、查看当前用户的定时任务
crontab -l

七、Keepalived的脑裂问题与解决

Keepalived的作用是专门用来监控、检测集群系统中各个服务器节点上服务的状态,如果检测到有一台服务器上的服务宕机或工作出现故障,并Keepalived将会把有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作。当服务器工作恢复正常后Keepalived又会自动将服务器加入到服务器集群中。这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。

7.1、什么是脑裂?

脑裂:指在一个高可用系统中,正在联系着的两台或多台服务器在指定时间内因为某些原因导致无法正常通信(无法互相检测到对方心跳而各自启动故障转移功能),本来为一个整体的系统分裂为两个独立节点运行。对于 Keepalived来说,出现脑裂的两个节点会互相争抢VIP的所有权(而此时两台服务器对都还活着并且正常运行),结果便会导致系统出现混乱(比如用keepalived做主备的架构环境,脑裂发生时会发现主备两台机器都拿到了虚拟VIP)。

7.2、keepalived脑裂产生的原因

脑裂产生的原因:
一般来说,裂脑的发生常见的有以下两种原因:

  1. 高可用 服务器对 之间常规网络通信故障。(硬件故障,比如:网线松动、断网了、服务器网卡等硬件坏了等);
  2. 高可用 服务器对 主备都开启了防火墙(firewalld 开启的话将会阻挡心跳消息的传输,这也是为什么前面提到要关闭防火墙的原因);

7.3、那么keepalived是如何解决或者防止脑裂问题的?

作为软件结构的设计,这里我们先不考虑常规的网络层面的通信故障(这个一般由网络安全人员去重点考虑,比如可以添加冗余的心跳线达到减少“裂脑”发生的概率),而这里我们主要从Keepalived配置上分析如何预防和避免脑裂问题的发生。

7.3.1、首先介绍如何防止

  1. 写检测脚本(此法最容易,通过keepalived提供的vrrp_script及track_script实现,原理同上面介绍的 HAProxy 心跳检测脚本,只需要把脚本里面内容改成节点互ping的逻辑即可),当检测到裂脑时强行关闭一个心跳节点(service keepalived stop),这样即可保证另一个节点正常工作;
  2. 做好对裂脑的监控报警,在问题发生时人为第一时间介入仲裁;

监控报警脚本检测思路:正常情况下keepalived的VIP地址是在主节点上的,如果在从节点发现了VIP,就设置报警信息。检测脚本splitbrain_check.sh参考如下:

#!/bin/bash
# 检查脑裂的脚本,在备节点上进行部署

#我们上面设置的虚拟 VIP
LB_VIP=172.22.40.1

while true

do
  ping -c 2 -W 3 $LB_VIP &>/dev/null
    if [ $? -eq 0 -a `ip add|grep "$LB_VIP"|wc -l` -eq 1 ];then
        echo "keepalived is brain."
        // TODO ...
    else
        echo "keepalived is ok"
    fi
    sleep 5
done

7.3.2、如何避免?

避免 Keepalived 脑裂,这里给大家推荐的是:使用Keepalived非抢占模式
HA的实际运行过程中,当主发生异常且后期恢复正常后,存在抢占或非抢占两种情况。

抢占式:当master宕机的时候backup会把虚拟ip抢过去,然后master恢复好后,又会把vip抢回来(因为 master的优先级高)这种就叫抢占式。
非抢占式:当master宕机的时候backup会把虚拟ip抢过去,然后master恢复好后,不会把vip抢回来,这种就叫非抢占式。

说白了就是:vip 不再随着主备切换而自动飘移,因为此时已经没有 master 这一说了,全是备。

7.3.2.1、keepalived非抢占配置

下面直接展示keepalived的非抢占配置。

主机配置如下:

! Configuration File for keepalived

#非抢占模式
#keepalived全局配置
global_defs {
    #keepalived检测到故障主备切换时发送邮件通知配置项。
    #这里我直接改成了调邮件和短信服务接口,没有使用keepalived的notify功能。
    #短信和邮件接口配置在/etc/keepalived/haproxy_check.sh脚本里。
    
    #每个keepalived节点的唯一标识,不能与备机相同。
    router_id keepalived_master_172-22-40-104
}

#检测HAProxy脚本
vrrp_script check_haproxy {
   script "/etc/keepalived/haproxy_check.sh" #脚本所在的目录
   interval 10 #检测 haproxy 心跳频率:每隔10秒检测一次
   weight 2 #权重
}

#虚拟路由器配置
vrrp_instance haproxy {
    state BACKUP #非抢占模式,必须都设置为BACKUP。
	nopreempt
    interface ens192 #绑定当前虚拟路由器所使用的物理网卡,如eth0、bond0等,可通过ifconfig获得。
    virtual_router_id 51 #每个虚拟路由器的唯一标识。同属一个虚拟路由器的多个keepalived节点必须相同,务必要确保在同一网络中此值唯一。
    priority 100 #当前物理节点在此虚拟路由器中的优先级,值越大优先级越高。注意:主机的优先权要比备机高。
    advert_int 1 #心跳检查频率,单位:秒。
    
    #认证机制
    authentication {
        auth_type PASS #认证类型
        auth_pass 1111 #秘钥,同一虚拟路由器的多个keepalived节点auth_pass值必须保持一致
    }

    #虚拟路由器的VIP,不指定网卡时默认添加在eth0上。在添加VIP地址时,需确保将要使用的VIP不存在,避免冲突。
    virtual_ipaddress {
        172.22.40.1 #对外开放的虚拟ip
    }

    #调用检测HAProxy的脚本
    track_script {
        check_haproxy
    }
}

备机配置如下:

! Configuration File for keepalived

#非抢占模式
#keepalived全局配置
global_defs {
    #keepalived检测到故障主备切换时发送邮件通知配置项。
    #这里我直接改成了调邮件和短信服务接口,没有使用keepalived的notify功能。
    #短信和邮件接口配置在/etc/keepalived/haproxy_check.sh脚本里。
    
    #每个keepalived节点的唯一标识,不能与备机相同。
    router_id keepalived_backup_172-22-40-105
}

#检测HAProxy脚本
vrrp_script check_haproxy {
   script "/etc/keepalived/haproxy_check.sh" #脚本所在的目录
   interval 10 #检测 haproxy 心跳频率:每隔10秒检测一次
   weight 2 #权重
}

#虚拟路由器配置
vrrp_instance haproxy {
    state BACKUP #设置虚拟路由器状态为BACKUP,表示为备。非抢占模式必须都设置为BACKUP。
	nopreempt
    interface ens192 #绑定当前虚拟路由器所使用的物理网卡,如eth0、bond0等,可通过ifconfig获得。
    virtual_router_id 51 #每个虚拟路由器的唯一标识。同属一个虚拟路由器的多个keepalived节点必须相同,务必要确保在同一网络中此值唯一。
    priority  90 #当前物理节点在此虚拟路由器中的优先级,值越大优先级越高。注意:主机的优先权要比备机高。
    advert_int 1 #心跳检查频率,单位:秒。
    
    #认证机制
    authentication {
        auth_type PASS #认证类型
        auth_pass 1111 #秘钥,同一虚拟路由器的多个keepalived节点auth_pass值必须保持一致
    }

    #虚拟路由器的VIP,不指定网卡时默认添加在eth0上。在添加VIP地址时,需确保将要使用的VIP不存在,避免冲突。
    virtual_ipaddress {
        172.22.40.1 #对外开放的虚拟ip
    }

    #调用检测HAProxy的脚本
    track_script {
        check_haproxy
    }
}

注意:
1、两个节点的state都必须配置为BACKUP
2、两个节点都必须加上配置 nopreempt
引用官方文档对nopreempt字段的说明:
“nopreempt” allows the lower priority machine to maintain the master role, even when a higher priority machine comes back online.
NOTE: For this to work, the initial state of this entry must be BACKUP.

根据上述描述,第一点提到的state必须配置为BACKUP就明白了。

3、其中一个节点的优先级必须要高于另外一个节点的优先级。

7.4、Keepalived脑裂复现及非抢占模式避免测试

7.4.1、最简单的复现步骤

  1. 在 master 节点 172.22.40.104 上开启防火墙:systemctl start firewalld.service
  2. 在 backup 节点 172.22.40.105 上 也开启防火墙:systemctl start firewalld.service
  3. 重启两个节点上的 keepalived 服务 即可复现(两个节点能正常通信,但是虚拟 ip 会同时出现在两个节点的网卡中,导致的现象是应用无法正常连接虚拟 ip 使用!)。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述

防火墙的常用操作命令:
#关闭防火墙
systemctl stop firewalld.service
#开启防火墙
systemctl start firewalld.service
#查看防火墙状态
systemctl status firewalld.service

7.4.2、使用非抢占模式配置 Keepalived,再次测试脑裂

1)改配置:
在这里插入图片描述
在这里插入图片描述

2)关掉防火墙(systemctl stop firewalld.service),重启 Keepalived 服务。
此时虚拟 ip 能正常使用。

3)再次开启172.22.40.104、172.22.40.105 的防火墙,重启 Keepalived 服务:

systemctl start firewalld.service
service keepalived stop
service keepalived start

结论:杀掉172.22.40.104节点的ke服务,vip 转移到172.22.40.105上,恢复172.22.40.104上的 ke 服务后,vip不会自动飘移到 40.104 上。

关于脑裂问题最后的总结:
1、Keepalived脑裂:Keepalived主备机器在某些原因下导致无法正常通信(成为master的Keepalived节点,会通过VRRP协议以每秒向backup节点发送VRRP包的方式通告自己是主并且运行正常),此时由于无法互相检测到对方心跳而各自启动故障转移功能,使得本来为一个主备一体的系统分裂为两个独立的keepalived节点运行,此现象即为脑裂。 
出现脑裂的两个节点会互相争抢VIP的所有权,抢占vip所有权的过程中虚拟ip是没法正常使用的。脑裂最坏的情况是导致主备节点都拿到vip的控制权,最终导致虚拟ip无法使用。

2、keepalived脑裂问题常见的原因:
1)服务器之间常规网络通信故障,比如断网、服务器网卡坏掉等;
2)服务器开启了防火墙,firewalld开启的话将阻挡心跳消息的传输; 
3)主备故障转移,有故障的节点服务恢复后,主备节点长时间的互相抢占vip权限;

3、keepalived脑裂预防和解决措施:
1)写检测脚本:通过keepalived提供的vrrp_script及track_script实现主备节点互ping,ping不通次数超过 3 次则强行关闭掉一个节点的 Keepalived 服务;---已加
2)做好对裂脑的监控报警,在问题发生时人为第一时间介入仲裁:正常情况下keepalived的VIP地址是在主节点上的,如果在从节点也发现了VIP,就设置报警信息。---已加
3)Keepalived采用非抢占式:---已采用
3.1)抢占式:当master宕机的时候backup会把虚拟ip抢过去,等master恢复后又会把vip抢回来。
3.2)非抢占式:当master宕机的时候backup会把虚拟ip抢过去,然后master恢复好后,不会把vip抢回来,虚拟ip将不再随着主备切换而自动飘移。
注意,非抢占模式并不能完全避免脑裂,只是能很大程度上减少脑裂发生的概率。

八、Keepalived邮件通知配置

一个高可用服务,应该具备当服务发生故障,能够第一时间做故障转移,从而保证服务的可用性,同时还应该第一时间通知管理员,以便管理员能够知道服务发生了转移,这样一来管理员也能第一时间去排查故障,让故障的节点在很短的时间重新上线,避免下次故障导致服务不可用;keepalived的故障通知邮件机制,是通过判断当前节点keepalived的角色来触发邮件通知;

keepalived 配置实现邮件的发送功能,后续补充!目前先在 haproxy心跳检测脚本里采用邮件和短信接口发送通知。

九、RabbitMQ其他介绍

详见 RabbitMQ相关资料


此操作流程仅供大家参考,如有不严谨的地方,欢迎大家指正并沟通!感谢!

最后

以上就是花痴百合为你收集整理的HAProxy+Keepalived搭建RabbitMQ高可用集群一、简介二、准备工作二、单节点RabbitMQ服务安装步骤三、普通集群配置四、镜像集群配置五、RabbitMQ3.5.6+HAProxy+Keepalived搭建RabbitMQ高可用镜像模式集群六、Keepalived 存活自检测七、Keepalived的脑裂问题与解决八、Keepalived邮件通知配置九、RabbitMQ其他介绍的全部内容,希望文章能够帮你解决HAProxy+Keepalived搭建RabbitMQ高可用集群一、简介二、准备工作二、单节点RabbitMQ服务安装步骤三、普通集群配置四、镜像集群配置五、RabbitMQ3.5.6+HAProxy+Keepalived搭建RabbitMQ高可用镜像模式集群六、Keepalived 存活自检测七、Keepalived的脑裂问题与解决八、Keepalived邮件通知配置九、RabbitMQ其他介绍所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部