HAProxy+Keepalived(VIP)搭建Rabbitmq高可用镜像队列

目标

  • 搭建一款三节点的Rabbitmq服务集群,满足高可用的要求
  • 要求高可用,保活,镜像队列,负载均衡。

主要组件

  • RabbitMQ 用于存储转发消息及镜像队列,
  • HAProxy 用于负载均衡到达rabbitmq的流量,
  • Keepalived 用于保活HAProxy(也可以保活rabbitmq),并对外提供VIP用于访问。
  • 下载地址
    • RabbitMQ
      • 官网
      • rpm包下载地址
    • HAProxy
    • KeepAlived

架构模型

HAProxy+Keepalived(VIP)搭建Rabbitmq高可用镜像队列_第1张图片

访问链路

HAProxy+Keepalived(VIP)搭建Rabbitmq高可用镜像队列_第2张图片
图片选自:RabbitMQ负载均衡(3)——Keepalived+HAProxy实现高可用的负载均衡

  • 客户端通过VIP建立通信链路;通信链路通过Keeaplived的Master节点路由到对应的HAProxy之上;HAProxy通过负载均衡算法将负载分发到集群中的各个节点之上。
  • 正常情况下客户端的连接通过图中左侧部分进行负载分发。
  • 当Keepalived的Master节点挂掉或者HAProxy挂掉无法恢复,那么Backup提升为Master,客户端的连接通过图中右侧部分进行负载分发

选型原因

  • 为什么要搭建多节点的消息队列?
    • 单节点rabbitmq存在宕机风险,因此需要搭建三台互相备份
  • 如何做到消息镜像的?
    • 镜像其实是一种策略,首先是将三台rabbitmq设置为集群,然后开启镜像策略,使得消息传递到一个队列时,会自动拷贝到其他镜像的队列。
  • 如果某一台接受到的压力过大,如何做到负载均衡?
    • rabbitmq集群本身不具备负载均衡的功能,需要配合其他软件使用,比如HAProxy,同样的道理,为了防止出现宕机问题,需要在集群中配置多台HAProxy。
  • 如果HAProxy宕机了,另外一台如何感知?并切换流量请求?
    • HAProxy在宕机时,keepalived有保活脚本,大概意思就是发现keepalived发现HAProxy不存在,就会启动它,过三秒发现还是没启动,那就关闭它,关闭它的时候,会触发vip漂移到另外一台上。
    • HAProxy 之间需要能够自动进行故障转移,通常的解决方案就是 KeepAlived。KeepAlived也是两台,一主一从,对外提供vip,主机宕机,从机会接管vip(具体见文末的彩蛋2)。
  • 本案例中选取了两台HAProxy做负载均衡,负载方式是每台HAProxy都负载三台Rabbitmq,还是每台负载其中的两台?
    • 负载均衡三台。满足极端情况下的高可用。
  • 万一有一台Rabbitmq挂了,那么HAProxy是否还会向其发送消息导致消息丢失?
    • HAProxy的.cfg文件中定义的有健康检查机制,参数fall在指定多少次不成功的健康检查后,认为该服务宕掉了。
    • 配置文件中:server node3 hadoop003:5672 check inter 5000 rise 2 fall 3 weight 1,这里的rise 2 fall 3 就是用于判断死活的。
  • 如果keepalived挂了,另一台keepalived如何work?
    • 这个问题我没有仔细研究,应该是两台keepalived互相有心跳保活,主机宕机,从机会立刻抢占vip.

简易搭建流程

  • 第一步:分别在不同虚拟机上安装RabbitMQ
  • 第二步:验证RabbitMQ安装成功
  • 第三步:搭建RabbitMQ镜像队列
  • 第四步:设置RabbitMQ镜像规则并验证
  • 第五步:搭建HAProxy
  • 第六步:HAProxy权限相关的操作
  • 第七步:搭建Keepalived
  • 第八步:keepalived权限相关的操作
  • 第九步:分别测试在不同宕机情况下,对消息传递的影响

详细搭建流程

  • 第一步:分别在不同虚拟机上安装RabbitMQ
# 安装rabbitmq之前的依赖erlang和socat
rpm -ivh erlang-22.0.7-1.el7.x86_64.rpm
yum -y install socat
rpm -ivh rabbitmq-server-3.7.17-1.el7.noarch.rpm

# 启动服务 和 设置开机自启
service rabbitmq-server start
chkconfig rabbitmq-server on

# 新增用户并授权,第三句的 / 表示在vhost ”/“ 上的permission
rabbitctl    add_user   username    password
rabbitctl    set_user_tags   username    administrator
rabbitctl    set_permissions   -p    /   username    ".*"   ".*"   ".*"
  • 第二步:验证RabbitMQ安装成功
# 配置rabbitmq的浏览器插件
rabbitmq-plugins   enable    rabbitmq_management
# 在浏览器输入 IP:15672  输入用户名和密码  登录验证是否成功 
# 点击浏览器中admin模块,看一下权限是否正确
  • 第三步:搭建RabbitMQ镜像队列。
# 保持三台机器的.erlang.cookie一致,通过find / -iname .erlang.cookie 全局搜,然后copy到其他两台的root下,一般在/var/lib/rabbitmq/下可以找到,scp到其他两台上
scp   xx/.erlang.cookie      root@IP:/root/

# 后台启动方式
rabbitmq-server -detached  #说明:该命令会同时启动 Erlang 虚拟机和 RabbitMQ 应用服务。而后文用到的 rabbitmqctl start_app 只会启动 RabbitMQ 应用服务, rabbitmqctl stop_app 只会停止 RabbitMQ 服务

# 集群模式,设置镜像队列,下面四句话分别在三台机器上执行,只有主机需要改成内存运行模式,才运行第三句的--ram
rabbitmqctl stop_app                              # 1.停止服务
rabbitmqctl reset                                 # 2.重置状态
# 3.节点加入,rabbit@hadoop001是集群的名字,请起的响亮点
rabbitmqctl join_cluster   --ram   rabbit@hadoop001   
rabbitmqctl start_app                             # 4.启动服务

# 查看镜像队列状态
rabbitmqctl cluster_status
# 分别在各自节点的/etc/hosts下设置相同的配置信息(copy),然后重启机器
IP1  hostname1
IP2  hostname2 
IP3  hostname3 

  • chkconfig命令

  • 第四步:设置RabbitMQ镜像规则并验证

# 设置policy
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
# 验证
任意选取一台Rabbitmq登陆,创建一个队列,然后去其他两台看看,该队列是否存在
  • 第五步:搭建HAProxy
# 找个文件夹解压
tar -zxvf haproxy-2.0.3.tar.gz
# 编译,其中TARGET=Linux26 是通过uname -a 来查看Linux内核版本的,我的版本是31,PREFIX的地址自己指定
make TARGET=Linux31  PREFIX=/usr/app/haproxy-2.0.3
make install PREFIX=/usr/app/haproxy-2.0.3
# haproxy.cfg是haproxy的配置文件,需要自己创建,然后去网上找别人写好的配置文件,启动的时候可能会引起报错,解决不了的直接删除
touch haproxy.cfg #这个文件后续会用于启动haproxy,位置最好放在haproxy/conf下,haproxy文件就是刚才的PREFIX指定的位置。
# 启动:就是用haproxy/sbin/haproxy去启动刚才的配置文件
/usr/app/haproxy-2.0.3/sbin/haproxy  -f   /usr/app/haproxy-2.0.3/conf/haproxy.cfg   # 启动报错见下方的 《haproxy安装过程中的坑》


  • 第六步:HAProxy权限相关的操作及验证
# HAproxy设置开机自启【源码包安装方式是没有启动脚本的,是能通过命令的方式进行启动和关闭,什么都不会输出,只能通过netstat 的方式进行验证】
#将HAProxy服务启动脚本放置到/etc/init.d/,启动脚本见下方【HAProxy服务启动脚本】
cp haproxy /etc/init.d/
chkconfig --add haproxy
chkconfig --list haproxy
service haproxy start|restart|stop|status
# 验证
浏览器输入IP:8100/stats 就可以看见haproxy的界面 #stats是你在haproxy.cfg的lister起的名字

  • HAProxy服务启动脚本
  • haproxy安装过程中的坑
# 启动报错
解决办法:先看报错信息中的数字,它对应哪一行出错,然后去配置文件中,要么删除要么修改,具体可以见下面的链接:HAProxy实战搭建

# 访问ip:8100/stats空页面:  
解决办法:修改bind 为 0.0.0.0:8080

# 出现:Proxy 'monitor(就是你起的lister名)': in multi-process mode, stats will be limited to process assigned  to the current request
解决办法:修改:nbproc=1

  • HAProxy实战搭建

  • 第七步:搭建Keepalived

#解压
tar -zxvf keepalived-2.0.18.tar.gz
cd keepalived-2.0.18

#安装keepalived的相关依赖
yum -y install libnl libnl-devel
#--prefix是指定安装路径,没有的话会帮你创建,/usr/app/是路径,也可以安装在/etc/local
./configure --prefix=/usr/app/keepalived-2.0.18

#编译
make && make install   #这一步可能会报错,需要你安装gcc或者openssl-devel,甚至涉及到换yum源,需要你yum repolist all.  yum clean all. yum makecache. yum install -y gcc-c++ tcl.  yum install -y openssl-devel. 

#进行环境配置,Keepalived 默认会从 /etc/keepalived/keepalived.conf 路径读取配置文件,所以需要将安装后的配置文件拷贝到该路径
make /etc/keepalived
#/usr/app选择自己的安装路径,keepalived.conf的配置见下面的链接
cp /usr/app/keepalived-2.0.18/etc/keepalived/keepalived.conf /etc/keepalived/

#将所有 Keepalived 脚本拷贝到 /etc/init.d/ 目录下:
#编译目录中的脚本,/usr/software/是之前你安装tar包的地方
cp /usr/software/keepalived-2.0.18/keepalived/etc/init.d/keepalived /etc/init.d/
#安装目录中的脚本
cp /usr/app/keepalived-2.0.18/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/app/keepalived-2.0.18/sbin/keepalived /usr/sbin/


  • 第八步:keepalived权限相关的操作
#加入系统:
chmod +x /etc/init.d/keepalived
chkconfig --add keepalived 或者  chkcoonfig keepalived on
#设置/取消开机自动启动
systemctl    enable/disable keepalived.service
#启动/停止
systemctl    start/stop    keepalived.service
#haproxy的存活情况的判断脚本,记住这个路径,需要写入到keepalived.conf中
chmod +x /etc/keepalived/haproxy_check.sh
#查看keepalived状态
service keepalived status 或者 systemctl status  keepalived.service

  • keepalived安装过程中的坑
    • keepalived的配置文件的权限只能是644,否则就行报错
    • keepalived.conf 配置文件和keepalived用于监控haproxy的存活情况的脚本haproxy_check.sh,可以参考这篇文档:基于 HAProxy + KeepAlived 搭建 RabbitMQ 高可用集群

测试方案

  • 测试方案:

    • 方案一:在下列情形下,访问VIP:15672,看看是否可以登陆rabbitmq的浏览器端。
    • 方案二:在下列情形下,分别发送消息至rabbitmq,看看是否有消息投递失误。
  • 测试情形:

    • 情景一:关闭某一台机器上的rabbitmq服务
    • 情景二:关闭某两台机器上的rabbitmq服务
    • 情景三:关闭某一台机器上的haproxy服务
    • 情景四:关闭某一台机器上的keepalived服务
    • 情景五:同时关闭某一台机器上的haproxy+keepalived服务
    • 情景六:同时分别关闭某一台机器上的haproxy和另一台机器上的keepalived服务
    • 情景七:关闭这样一台机器(同时含有rabbitmq+haproxy+keepalived服务)
    • 情景八:关闭这样两台机器(一台同时含有rabbitmq+haproxy+keepalived服务,一台仅含有rabbitmq)
  • 测试结果:

    • 方案一:全部通过
    • 方案二:待和RabbitMQ实现消息100%投递一起测试
  • 彩蛋1:

    • 在做测试一的时候,我是采用浏览器登录来查询的,但是发现宕掉rabbitmq1的时候,浏览器访问不了,我一度以为haproxy不起作用,实际上是haproxy的配置文件仅配置了5672,却没有对15672的端口进行配置,要么我改方案,不要浏览器测试,采用代码链接测试,要么在haproxy.cfg中增加15672的端口转发listen规则,在.cfg文件增加如下内容:
# 绑定配置
listen rabbitmq_browser
    # 注意此处的15671,你也可以用任何不冲突的端口,然后浏览器访问vip:15671就可以了
    bind :15671
    # 注意此处的http
    mode http
    # 采用加权轮询的机制进行负载均衡
    balance roundrobin
    # RabbitMQ 集群节点配置
    server 节点名 hadoop001:15672 check inter 5000 rise 2 fall 3 weight 1
    server node2 hadoop002:15672 check inter 5000 rise 2 fall 3 weight 1
    server node3 hadoop003:15672 check inter 5000 rise 2 fall 3 weight 1
  • 彩蛋2:
    • 在做测试的时候,我使用systemctl stop Haproxy.server 和 service Haproxy stop 去关闭Haproxy,但是再用service Haproxy status查看状态的时候,发现依旧在运行,我一度以为指令无效或者我装了一个假Haproxy。
      • 实际原因是:我在keepalived里面配置的那个ha_check.sh脚本,会不停检查Haproxy,一旦查不到就重启Haproxy,sleep三秒还是不起来,就停掉该服务,然后keepalived的其他组件会发现检测的服务关闭,就会通知另一台备份的Haproxy开始承担主角工作。
    • keepalived的配置文件中,有个state参数,一般文章建议设置主为master,从为backup,此处建议都设置为backup,这样的话,先启动的是主,当发生vip漂移的时候,原来的主启动不会再次发生漂移,减少网络抖动。

你可能感兴趣的:(高并发,高可用,高性能专题)