RabbitMQ + 镜像队列 + HAProxy 实现负载均衡的集群


一、集群管理(RabbitMQ扩容)

1. 环境介绍

hostname ip
mq1 192.168.80.16
mq2 192.168.80.17
mq3 192.168.80.18
mqhaproxy 192.168.80.19

单机部署

单机版安装地址:RabbitMQ3.8.4安装和配置

注意:修改三台节点的hostname文件,设置主机名称,分别mq1/mq2/mq3

修改三台节点的/etc/hosts文件,设置节点名称和ip地址的映射关系

2. 从mq1拷贝.erlang.cookie到mq2、mq3的相应目录(元数据共享)

如果没有该文件,手动创建 /var/lib/rabbitmq/.erlang.cookie ,生成Cookie字符串,或者启动一次RabbitMQ自动生成该文件。生产中推荐使用第三方工具生成。

2.1 我们首先在mq1上启动单机版RabbitMQ,以生成Cookie文件:
 systemctl start rabbitmq-server

2.2 开始准备同步 .erlang.cookie 文件
 RabbitMQ的集群依赖Erlang的分布式特性,需要保持Erlang Cookie一致才能实现集群节点的认证和通信,我们直接使用scp命令从node1远程传输。
 scp /var/lib/rabbitmq/.erlang.cookie root@node3:/var/lib/rabbitmq/scp /var/lib/rabbitmq/.erlang.cookie root@node4:/var/lib/rabbitmq/


同步完 .erlang.cookie 文件 后,在当前节点就可以访问其他节点

2.3 修改mq2和mq3上该文件的所有者为:rabbitmq:rabbitmq
 chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie


注意: .erlang.cookie文件权限为400

3. 使用下述命令启动mq2和mq3上的RabbitMQ:

 systemctl start rabbitmq-server

4. 将mq2和mq3这两个节点加入到集群中(默认情况下:一个节点就是一个集群)

4.1 以mq1节点为集群,查看集群状态:此时运行节点只有mq1节点
 rabbitmqctl cluster_status

4.2 停止Erlang VM上运行的RabbitMQ应用,保持Erlang VM的运行
 rabbitmqctl stop_app

4.3 移除当前RabbitMQ虚拟主机中的所有数据:重置
 rabbitmqctl reset

4.4 将当前RabbitMQ的主机加入到rabbit@node2这个虚拟主机的集群中。一个节点也是集群。
 rabbitmqctl join_cluster rabbit@mq1

4.5 启动当前Erlang VM上的RabbitMQ应用
 rabbitmqctl start_app

4.6 再次mq1节点集群状态,此时多出一个节点mq2
 rabbitmqctl cluster_status

4.7 使用相同的方式,将mq3也加入到当前集群中

4.8 再次mq1节点集群状态,此时多出一个节点mq2
 rabbitmqctl cluster_status

注意:
 1. rabbit@node2 表示RabbitMQ节点名称,默认前缀就是 rabbit , @ 之后是当前虚拟主机所在的物理主机 hostname 。2. 注意检查下hostname要可以相互ping通3. join_cluster默认是使用disk模式,后面可以加入参数--ram启用内存模式

5. 移出集群节点使用:

# 将虚拟主机(RabbitMQ的节点)rabbit@node3从集群中移除,但是rabbit@node3还保留集群信息
# 还是会尝试加入集群,但是会被拒绝。可以重置rabbit@node3节点。rabbitmqctl forget_cluster_node rabbit@mq2


重启节点报错

重置后,重新启动

查看集群状态:只有其本身(可以再次将此节点加入现有集群)

6. 其他操作命令:

#修改集群名称(任意节点执行都可以)rabbitmqctl set_cluster_name  集群名称   (只要cookie文件一致,就可以进行名称的修改,修改节点不一定要在一个集群中)
#查看集群状态(任意节点执行都可以)rabbitmqctl cluster_status
6.1 修改集群名称
 rabbitmqctl set_cluster_name  dabingrabbits

6.2 将mq2重新加回集群

7. web控制台

在三个RabbitMQ节点上的任意一个添加用户,设置用户权限,设置用户标签

 rabbitmqctl add_user root 123456rabbitmqctl set_permissions --vhost "/" root ".*" ".*" ".*"rabbitmqctl set_user_tags --vhost "/" root administrator

可以到web控制台查看集群信息

如果要看到所有RabbitMQ节点上的运行情况,所有节点都需要启用rabbitmq_management 插件

二、RabbitMQ镜像集群配置(消息分片存储,单点故障)

RabbitMQ中队列的内容是保存在单个节点本地的(声明队列的节点)。跟交换器和绑定不同,它们是对于集群中所有节点的。

如此,则队列内容存在单点故障,解决方式之一就是使用镜像队列。在多个节点上拷贝队列的副本。

 每个镜像队列包含一个master,若干个镜像。master存在于称为master的节点上。所有的操作都是首先对master执行,之后广播到镜像。这涉及排队发布,向消费者传递消息,跟踪来自消费者的确认等。镜像意味着集群,不应该WAN使用。

发布到队列的消息会拷贝到该队列所有的镜像。消费者连接到master,当消费者对消息确认之后,镜像删除master确认的消息。

队列的镜像提供了高可用,但是没有负载均衡。

HTTP API和CLI工具中队列对象的字段原来使用的是slave代表secondaries,现在盖字段的存在仅是为了向后兼容,后续版本会移除。

可以使用策略随时更改队列的类型,可以首先创建一个非镜像队列,然后使用策略将其配置为镜像队列或者反过来。非镜像队列没有额外的基础设施,因此可以提供更高的吞吐率。

master选举策略:

 1. 最长的运行镜像    升级为主镜像,前提是假定它与主镜像完全同步。如果没有与主服务器同步的镜像,则仅存在于主服务器上的消息将丢失。2. 镜像认为所有以前的消费者都已突然断开连接。它重新排队已传递给客户端但正在等待确认的所有消息。这包括客户端已为其发出确认的消息,例如,确认是在到达节点托管队列主节点之前在线路上丢失了,还是在从主节点广播到镜像时丢失了。在这两种情况下,新的主服务器都别无选择,只能重新排队它尚未收到确认的所有消息。3. 队列故障转移时请求通知的消费者将收到取消通知。当镜像队列发生了master的故障转移,系统就不知道向哪些消费者发送了哪些消息。已经发送的等待确认的消息会重新排队4. 重新排队的结果是,从队列重新使用的客户端必须意识到,他们很可能随后会收到已经收到的消息。5. 当所选镜像成为主镜像时,在此期间发布到镜像队列的消息将不会丢失(除非在提升的节点上发生后续故障)。发布到承载队列镜像的节点的消息将路由到队列主服务器,然后复制到所有镜像。如果主服务器发生故障,则消息将继续发送到镜像,并在完成向主服务器的镜像升级后将其添加到队列中。6. 即使主服务器(或任何镜像)在正在发布的消息与发布者收到的确认之间失败,由客户端使用发布者确认发布的消息仍将得到确认。从发布者的角度来看,发布到镜像队列与发布到非镜像队列没有什么不同。

给队列添加镜像要慎重。

ha-mode ha-params 结果
exactly count 设置集群中队列副本的个数(镜像+master)。1表示一个副本;也就是master。如果master不可用,行为依赖于队列的持久化机制。2表示1个master和1个镜像。如果master不可用,则根据镜像推举策略从镜像中选出一个做master。如果节点数量比镜像副本个数少,则镜像覆盖到所有节点。如果count个数少于集群节点个数,则在一个镜像宕机后,会在其他节点创建出来一个镜像。将“exactly”模式与“ha-promote-on-shutdown”: “ always”一起使用可能很危险,因为队列可以在整个集群中迁移并在关闭时变得不同步。
all (none) 镜像覆盖到集群中的所有节点。当添加一个新的节点,队列就会复制过去。这个配置很保守。一般推荐N/2+1个节点。在集群所有节点拷贝镜像会给集群所有节点施加额外的负载,包括网络IO,磁盘IO和磁盘空间使用。
nodes node
names
在指定node name的节点上复制镜像。node name就是在rabbitmqctlcluster_status命令输出中的node name。如果有不属于集群的节点名称,它不报错。如果指定的节点都不在线,则仅在客户端连接到的声明镜像的节点上创建镜像。

接下来,启用镜像队列:

# 对/节点配置镜像队列,使用全局复制rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'# 配置过半(N/2 + 1)复制镜像队列rabbitmqctl set_policy ha-halfmore "queueA" '{"ha-mode":"exactly", "ha-params":2}'# 指定优先级,数字越大,优先级越高rabbitmqctl set_policy --priority 1 ha-all "^" '{"ha-mode":"all"}'
2.1 创建一个测试队列

2.2 配置队列为 过半(N/2 + 1)复制镜像队列(可以使用正则匹配队列名称,2表示一主一从)
 rabbitmqctl  set_policy  ha_test  "^queue.*test$"   '{"ha-mode":"exactly", "ha-params":2}'



2.3 关闭镜像mirrors所在的节点mq3

2.4 查看队列信息

2.5 将队列设置成非镜像队列

2.6 在任意一个节点上面执行即可。默认是将所有的队列都设置为镜像队列,在消息会在不同节点之间复制,各节点的状态保持一致。


点击上图中的queueA,查看该队列的细节:

其他细节可以查看官方文档:
 https://www.rabbitmq.com/ha.html

三、负载均衡-HAProxy

将客户端的连接和操作的压力分散到集群中的不同节点,防止单个或几台服务器压力过大成为访问的瓶颈,甚至宕机。

HAProxy是一款开源免费,并提供高可用性、负载均衡以及基于TCP和HTTP协议的代理软件,可以支持四层、七层负载均衡,经过测试单节点可以支持10W左右并发连接。

LVS是工作在内核模式(IPVS),支持四层负载均衡,实测可以支撑百万并发连接。

Nginx支持七层的负载均衡(后期的版本也支持四层了),是一款高性能的反向代理软件和Web服务器,可以支持单机3W以上的并发连接。

这里我们使用HAProxy来做RabbitMQ的负载均衡,通过暴露VIP给上游的应用程序直接连接,上游应用程序不感知底层的RabbitMQ的实例节点信息。

3.1 环境准备

hostname ip
mqhaproxy 192.168.80.19

3.2 安装方式一:rpm安装

 wget https://www.haproxy.org/download/2.0/src/haproxy-2.0.1.tar.gztar -zxf haproxy-2.1.0.tar.gzyum install gcc -ycd haproxy-2.1.0make TARGET=linux-glibcmake installmkdir /etc/haproxy#赋权groupadd -r -g 149 haproxy# 添加用户useradd -g haproxy -r -s /sbin/nologin -u 149 haproxy#创建haproxy配置文件touch /etc/haproxy/haproxy.cfg
下载haproxy安装包

解压haproxy安装包

安装编译环境gcc,编译安装包

安装haproxy

安装方式二:yum安装(略)

yum -y install haproxy

如何使用yum安装的,那么haproxy默认在/usr/sbin/haproxy,且会自动创建配置文件/etc/haproxy/haproxy.cfg

3.3 添加用户

赋权
 groupadd -r -g 149 haproxyuseradd -g haproxy -r -s /sbin/nologin -u 149 haproxy

3.4 配置HAProxy

创建配置文件haproxy.cfg ,并修改配置文件haproxy.cfg

 mkdir /etc/haproxytouch /etc/haproxy/haproxy.cfgvim /etc/haproxy/haproxy.cfg

配置文件都做了详细注释,参考如下:

 globallog 127.0.0.1 local0 info# 服务器最大并发连接数;如果请求的连接数高于此值,将其放入请求队列,等待其它连接被释放;maxconn 5120# chroot /tmp# 指定用户uid 149# 指定组gid 149# 让haproxy以守护进程的方式工作于后台,其等同于“-D”选项的功能# 当然,也可以在命令行中以“-db”选项将其禁用;daemon# debug参数quiet# 指定启动的haproxy进程的个数,只能用于守护进程模式的haproxy;# 默认只启动一个进程,# 鉴于调试困难等多方面的原因,在单进程仅能打开少数文件描述符的场景中才使用多进程模式;# nbproc 20nbproc 1pidfile /var/run/haproxy.piddefaultslog global# tcp:实例运行于纯TCP模式,第4层代理模式,在客户端和服务器端之间将建立一个全双工的连接,# 且不会对7层报文做任何类型的检查;# 通常用于SSL、SSH、SMTP等应用;mode tcpoption tcplogoption dontlognullretries 3option redispatchmaxconn 2000# contimeout 5stimeout connect 5s# 客户端空闲超时时间为60秒则HA 发起重连机制timeout client 60000# 服务器端链接超时时间为15秒则HA 发起重连机制timeout server 15000listen rabbitmq_cluster# VIP,反向代理到下面定义的三台Real Serverbind 192.168.80.19:5672#配置TCP模式mode tcp#简单的轮询balance roundrobin# rabbitmq集群节点配置# inter 每隔五秒对mq集群做健康检查,2次正确证明服务器可用,2次失败证明服务器不可用,并且配置主备机制server rabbitmqNode1 192.168.80.16:5672 check inter 5000 rise 2 fall 2server rabbitmqNode2 192.168.80.17:5672 check inter 5000 rise 2 fall 2server rabbitmqNode3 192.168.80.18:5672 check inter 5000 rise 2 fall 2#配置haproxy web监控,查看统计信息listen statsbind 192.168.80.19:9000mode httpoption httplog# 启用基于程序编译时默认设置的统计报告stats enable#设置haproxy监控地址为http://mq1:9000/rabbitmq-statsstats uri /rabbitmq-stats# 每5s刷新一次页面stats refresh 5s

拷贝上述配置信息到配置文件haproxy.cfg

3.5 启动HAProxy:

 haproxy -f /etc/haproxy/haproxy.cfg


检查进程状态,还可以通过访问http://vip:9000/rabbitmq-stats查看状态

3.6 关闭:

 kill -9 <pid>

3.7 接下来,可以在代码中直接测试,代码配置直接连接到HAProxy和监听端口上即可(略)

集群的搭建就已经完成了。

四、监控

RabbitMQ自带的(Management插件)管理控制台功能比较丰富,不仅提供了Web UI界面,还暴露了很多HTTP API的能力。其中也具备基本的监控能力。此外,自带的命令行工具(例如:rabbitmqctl )也比较强大。

不过这些工具都不具备告警的能力。在实际的生产环境中,我们需要知道负载情况和运行监控状态(例如:系统资源、消息积压情况、节点健康状态等),而且当发生问题后需要触发告警。像传统的监控平台Nagios、Zabbix等均提供了RabbitMQ相关的插件支持。

另外,当前云原生时代最热门的Prometheus监控平台也提供了rabbitmq_exporter,结合Grafana漂亮美观的dashboard(可以自定义,也可以在仓库选择一些现有的),我们目前公司就是使用Prometheus + Grafana来监控RabbitMQ的,并实现了水位告警通知。

感兴趣的同学可以自己研究。https://www.rabbitmq.com/prometheus.html

RabbitMQ + 镜像队列 + HAProxy 实现负载均衡的集群相关推荐

  1. linux 内核round-robin scheduler代码,用LVS构架负载均衡Linux集群系统 linux lvs

    never queue scheduling --- IPVS application helper FTP protocol helper 以上所有项建议全部选择. (4)Networking op ...

  2. Dubbo负载均衡与集群容错

    文章目录 负载均衡与集群容错 Invoker 服务目录 RegistryDirectory StaticDirectory 服务路由 Cluster 负载均衡 负载均衡与集群容错 Invoker 在D ...

  3. 使用LVS和Keepalived搭建高可用负载均衡服务器集群

    目录 1.什么是LVS和Keepalived 2.负载均衡服务器集群示例环境搭建及安装配置 2.1.环境网络拓扑结构 2.2.安装ipvsadm软件 2.3.安装keepalived 2.4.配置网络 ...

  4. 使用LVS(Linux Virtual Server)在Linux上搭建负载均衡的集群服务

    使用LVS(Linux Virtual Server)在Linux上搭建负载均衡的集群服务 一.基于于NAT的LVS的安装与配置. 1. 硬件需求和网络拓扑                       ...

  5. web应用的负载均衡、集群、高可用(HA)解决方案

    web应用的负载均衡.集群.高可用(HA)解决方案 参考文章: (1)web应用的负载均衡.集群.高可用(HA)解决方案 (2)https://www.cnblogs.com/huojg-21442/ ...

  6. 基于nginx的tomcat负载均衡和集群(超简单)

    今天看到"基于apache的tomcat负载均衡和集群配置 "这篇文章成为javaEye热点. 略看了一下,感觉太复杂,要配置的东西太多,因此在这里写出一种更简洁的方法. 要集群t ...

  7. nginx 反向代理负载均衡 tomcat集群应用

    nginx 反向代理负载均衡 tomcat集群应用 环境介绍: 系统:centos5.8_64 192.168.0.201:nginx服务器 192.168.0.202:tomcat服务器 192.1 ...

  8. 浅谈web应用的负载均衡、集群、高可用(HA)解决方案

    浅谈web应用的负载均衡.集群.高可用(HA)解决方案 转载于:https://www.cnblogs.com/hfultrastrong/p/7887420.html

  9. apache的tomcat负载均衡和集群配置

    略看了一下,感觉太复杂,要配置的东西太多,因此在这里写出一种更简洁的方法. 要集群tomcat主要是解决SESSION共享的问题,因此我利用memcached来保存session,多台TOMCAT服务 ...

最新文章

  1. node给java发送文件_如何实现node上传文件到后台?
  2. 基因组组装----k-mer
  3. hdu6376 度度熊剪纸条 思维
  4. myeclipse的buildpath 和lib引入的区别
  5. 计算机视觉编程——图像内容分类
  6. Python面试题目--汇总
  7. NetCore 依赖注入之服务之间的依赖关系
  8. 《认清C++语言》之--内存管理
  9. android中读取properties文件
  10. Newtonsoft 六个超简单又实用的特性,值得一试 【上篇】
  11. 吴恩达机器学习【第三天】线性代数基础知识
  12. 使用matplotlib绘制K线图以及和成交量的组合图
  13. gxworks2软件测试对话框,超实用!GX Works2软件的启动与窗口功能应用
  14. 人脸数据集汇总(附百度云盘链接)
  15. Linux下使用和配置magick
  16. Python中神奇的第三方库:Faker假数据生成器
  17. 【渝粤题库】陕西师范大学100021 大学语文 作业 (专升本、高起专、高起本)
  18. 【数学】徐小湛第七高等数学新版
  19. oracle删除双引号,oracle 表名 双引号 删除
  20. 字节跳动大数据开发面试题-附答案

热门文章

  1. Tengine(Nginx)动静分离简要配置
  2. 20120530, BGP3
  3. windows系统上安装mysql操作过程及常见错误处理
  4. MySQL介绍及安装(一)
  5. 前端基础7:a标签常用方法和元素居中方式,响应式@media
  6. iOS AFN监听网络状态
  7. Ubuntu香港apt-get源
  8. 改进粒子群优化算法(PURPSO)的MATLAB源程序
  9. 如何在while和for中使用ssh
  10. MySQL行锁 表锁理解