RabbitMQ-集群
回到正题,为什么搭建rabbitmq集群?rabbitmq集群有那些模式?如何搭建Rabbitmq集群?rabbitmq镜像高可用策略有那些?
设计集群的目的
- 允许消费者和生产者在 RabbitMQ 节点崩溃的情况下继续运行。
- 通过增加更多的节点来扩展消息通信的吞吐量。
rabbitmq有3种模式 ------ 但集群模式是2种
详细如下:
单一模式:即单机情况不做集群,就单独运行一个rabbitmq而已。(上一遍就是单一模式)
普通模式:默认模式,以两个节点(rabbit01、rabbit02)为例来进行说明。对于Queue来说,消息实体只存在于其中一个节点rabbit01(或者rabbit02),rabbit01和rabbit02两个节点仅有相同的元数据,即队列的结构。当消息进入rabbit01节点的Queue后,consumer从rabbit02节点消费时,RabbitMQ会临时在rabbit01、rabbit02间进行消息传输,把A中的消息实体取出并经过B发送给consumer。所以consumer应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理Queue。否则无论consumer连rabbit01或rabbit02,出口总在rabbit01,会产生瓶颈。当rabbit01节点故障后,rabbit02节点无法取到rabbit01节点中还未消费的消息实体。如果做了消息持久化,那么得等rabbit01节点恢复,然后才可被消费;如果没有持久化的话,就会产生消息丢失的现象。
镜像模式:把需要的队列做成镜像队列,存在与多个节点属于RabbitMQ的HA方案。该模式解决了普通模式中的问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在客户端取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用。
集群配置方式
- cluster:不支持跨网段,用于同一个网段内的局域网;可以随意的动态增加或者减少;节点之间需要运行相同版本的 RabbitMQ 和 Erlang。
- federation:应用于广域网,允许单台服务器上的交换机或队列接收发布到另一台服务器上交换机或队列的消息,可以是单独机器或集群。federation 队列类似于单向点对点连接,消息会在联盟队列之间转发任意次,直到被消费者接受。通常使用 federation 来连接 internet 上的中间服务器,用作订阅分发消息或工作队列。
- shovel:连接方式与 federation 的连接方式类似,但它工作在更低层次。可以应用于广域网。
- RAM node:内存节点将所有的队列、交换机、绑定、用户、权限和 vhost 的元数据定义存储在内存中,好处是可以使得像交换机和队列声明等操作更加的快速。
- Disk node:将元数据存储在磁盘中,单节点系统只允许磁盘类型的节点,防止重启 RabbitMQ 的时候,丢失系统的配置信息。
节点类型
了解了基础概念后,我们开始搭建镜像集群:
环境介绍:
RabbitMQ-节点 |
IP |
类型 |
系统 |
node1 |
192.168.1.111 |
DISK |
CentOS 7.0 - 64位 |
node2 |
192.168.1.222 |
D |
CentOS 7.0 - 64位 |
整体架构:
1: 把前一遍文档的搭建步骤在node2机器上面搭建一遍。
https://www.cnblogs.com/jim-xu/p/11592022.html
2: 编辑hosts文件( node1 和 node2 )
[root@node1/2 ~]# vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.6.111 node1
192.168.6.222 node2
3:复制Erlang Cookie,保证node1和node2的cookie一致
Erlang Cookie 是保证不同节点可以相互通信的密钥,要保证集群中的不同节点相互通信必须共享相同的 Erlang Cookie。具体的目录存放在/var/lib/rabbitmq/.erlang.cookie
[root@node1 ~]# scp /var/lib/rabbitmq/.erlang.cookie root@node2:/var/lib/rabbitmq
4:把node2加入到 node1 中,以node1 作为集群中心。
如下操作请在node2机器操作:
[root@node1 ~]# rabbitmqctl stop_app
[root@node1 ~]# rabbitmqctl reset
//默认是磁盘节点,如果是内存节点的话,需要加--ram参数
[root@node1 ~]# rabbitmqctl join_cluster rabbit@node1
启动:
[root@node1 ~]# rabbitmqctl start_app
5:查看集群状态:node1 或者 node2 都可以执行此命令
[root@node2 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@node1
[{nodes,[{disc,[rabbit@node1,rabbit@node2]}]},
{running_nodes,[rabbit@node2,rabbit@node1]},
{cluster_name,<<"rabbit@node1">>},
{partitions,[]},
{alarms,[{rabbit@node2,[]},{rabbit@node1,[]}]}]
[root@node1 ~]#
6 : rabbitMQ Web 管理界面,查看集群的信息:
到此集群已经形成,此时只是普通模式的集群状态,我们需要改成镜像模式实现高可用性的集群。
7: 镜像集群
镜像队列实现了 RabbitMQ 的高可用性(HA),具体的实现策略如下所示:
ha-mode |
ha-params |
功能 |
all |
空 |
镜像队列将会在整个集群中复制。当一个新的节点加入后,也会在这 个节点上复制一份。 |
exactly |
count |
镜像队列将会在集群上复制 count 份。如果集群数量少于 count 时候,队列会复制到所有节点上。如果大于 Count 集群,有一个节点 crash 后,新进入节点也不会做新的镜像。 |
nodes |
node name |
镜像队列会在 node name 中复制。如果这个名称不是集群中的一个,这不会触发错误。如果在这个 node list 中没有一个节点在线,那么这个 queue 会被声明在 client 连接的节点。 |
首先镜像模式要依赖policy模块,这个模块是做什么用的呢?
policy中文来说是政策,策略的意思,那么他就是要设置,那些Exchanges或者queue的数据需要复制,同步,如何复制同步?对就是做这些的。
这里有点内容的,我先上例子慢慢说:
[root@node1 ~]# rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
参数意思为:
ha-all:为策略名称。
^:为匹配符,只有一个^代表匹配所有,^xujin为匹配名称为xujin的exchanges或者queue。
ha-mode:为匹配类型,他分为3种模式:all-所有(所有的queue),exctly-部分(需配置ha-params参数,此参数为int类型比如3,众多集群中的随机3台机器),nodes-指定(需配置ha-params参数,此参数为数组类型比如["rabbit@node1","rabbit@node2"]这样指定为node1与node2这2台机器。)。
8: 配置镜像模式 在node1主节点执行如下命令:
[root@node1 ~]# rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
Setting policy "ha-all" for pattern "^" to "{\"ha-mode\":\"all\"}" with priority "0"
[root@node1 ~]#
也可以在web界面添加:
那么我们怎么知道现在是镜像模式了呢????
9: 模拟创建一个队列queue ,看队列是否会自动的复制到另外一个节点上面
web界面操作,模拟在node1 节点上面创建一个队列queue
10: 查看队列queue - 是否产生镜像了
web点击queue名称xujin-test :
到此rabbitmq 的镜像模式集群,就搭建好了。
下一篇将讲解如何利用haproxy搭建成高可用性(HA)