图解集群
一个好消息是,RabbitMQ这款消息队列中间件产品本身是基于Erlang编写,Erlang语言天生具备分布式特性(通过同步Erlang集群各节点的magic cookie来实现)。因此,RabbitMQ天然支持集群。这使得RabbitMQ本身不需要像ActiveMQ、Kafka那样借助ZooKeeper实现集群搭建。
先简单说两个问题,后面会详细介绍:
❶ 如何实现各个节点上的队列消息的同步?
我们只需在搭建好集群后,添加一个镜像队列的策略即可。
❷ 如何实现多个节点的透明代理?如何实现各个节点的负载均衡?
HAProxy可以解决这一切。
好了,下面看图理解镜像队列和HAProxy的作用:
集群搭建
刚刚说过,RabbitMQ兔子窝的集群搭建并不需要借助ZooKeeper,直接使用自身提供的命令即可实现。
下面,搭建一个伪集群进行演示(伪集群用端口号区分,真实集群用IP地址区分):
## 基本思路 ##
默认的rabbitmq节点(rabbit@ubuntu)开启在5672端口上,对应web控制台在15672端口上。
我们在演示的时候,不使用它,而是自己创建两个节点,并声明端口防止冲突:
rabbit1@ubuntu节点:5673/15673,作为master
rabbit2@ubuntu节点:5674/15674,作为slave
## 启动第一个节点 ##
RABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15673}]" RABBITMQ_NODENAME=rabbit1 rabbitmq-server start
## 启动第二个节点 ##
RABBITMQ_NODE_PORT=5674 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15674}]" RABBITMQ_NODENAME=rabbit2 rabbitmq-server start
## 主节点 ##
rabbitmqctl -n rabbit1 stop_app
rabbitmqctl -n rabbit1 reset
rabbitmqctl -n rabbit1 start_app
## 从节点 ##
rabbitmqctl -n rabbit2 stop_app
rabbitmqctl -n rabbit2 reset
rabbitmqctl -n rabbit2 join_cluster rabbit1@主机名
rabbitmqctl -n rabbit2 start_app
## 查看集群状态 ##
rabbitmqctl cluster_status -n rabbit1
镜像队列
首先明确,在配置好RabbitMQ集群后,是不保证队列的高可用性的。也就是说,集群建立好了,但队列的消息之间仍旧不是同步的。一行命令即可配置好镜像队列:
rabbitmqctl set_policy my_ha "^" '{"ha-mode":"all"}'
下面,来谈谈镜像队列。
这其实是分布式中一个老生常谈的主从模型。生产和消费的操作其实都是在master上的queue上进行的,然后讲结果对所有的slave的queue进行同步。
当slave节点挂掉了怎么办?除了记录一下日志,什么都不用做。当master节点挂掉了怎么办?选举出slave成为master——选举的依据是slave与master的同步情况。一般来说,最老的slave节点,与master的同步情况是最好的。
消息如何进行同步?看上图就能知道,master与slave的关系是一个基于GM协议的循环链表。master发一个消息,该消息走一圈最终回到master,就能知道集群是否已经发生同步。
最后补充说明一下,同步的基本单位是队列,而不是节点。
负载均衡
借助HAProxy可轻易实现负载均衡,并且同时实现集群的透明代理,非常方便。
核心配置只有几行:
listen rabbitmq_cluster
bind 0.0.0.0:5672
balance roundrobin
server node1 127.0.0.1:5673 check inter 5000 rise 2 fall 2
server node2 127.0.0.1:5674 check inter 5000 rise 2 fall 2
下面,来谈谈这个强大的HAProxy。
首先,什么是HAProxy?
HAProxy是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,且支持虚拟机,是一种免费、快速、可靠的解决方案。
HAProxy实现了一种事件驱动的单一进程模型,此模型支持非常大的并发连接数。而多进程或多线程模型受到内存和调度的限制,是很难处理数千并发连接的。
另外,HAProxy支持全透明代理,也就是说,我们可以让后端的集群透明化,对外仅仅表现为一台机器。
谈到HAProxy,不得不谈到负载均衡的其他两种解决方案:Nginx和LVS。
Nginx的优点:
1)Nginx工作在OSI第7层,可以针对http应用做一些分流的策略
2)Nginx对网络的依赖非常小,理论上能ping通就能进行负载功能
3)Nginx安装和配置比较简单
4)Nginx可以通过端口检测服务器后端
5)Nginx不仅仅是一款优秀的负载均衡/反向代理软件,它同时也是功能强大的Web应用服务器
Nginx的缺点:
1)Nginx不支持url检测服务器后端
2)Nginx仅能支持http、https和Email协议
3)Nginx的Session保持能力,Cookie引导能力相对欠缺
HAProxy的优点:
1)HAProxy是支持虚拟主机的
2)HAProxy支持url检测服务器后端
3)HAProxy跟LVS一样,本身仅仅就只是一款负载均衡软件;单纯从效率上来讲HaProxy更会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的
4)HAProxy的算法较多,支持8种负载均衡算法
5)HAProxy支持Session的保持,Cookie的引导
HAProxy的缺点:
1)不支持POP/SMTP协议
2)多进程模式支持不够好
3)HAProxy有免费开源的管理后台,Nginx的管理后台要收费
LVS的优点:
1)抗负载能力强,在负载均衡软件里的性能最强的
2)工作稳定,因为其本身抗负载能力很强,自身有完整的双机热备方案
3)应用范围比较广,因为LVS工作在4层
LVS的缺点:
1)软件本身不支持正则表达式处理,不能做动静分离,这是它被Nginx/HAProxy打败的原因
2)当网站体量变大时,LVS解决方案就力不从心的,这也是它被Nginx/HAProxy打败的原因
🐰 Rabbit~