RabbitMQ的集群是依赖erlang集群的,而erlang集群是通过.erlang.cookie文件进行通信认证的,所以我们使用RabbitMQ集群时只需要配置一下.erlang.cookie文件即可。下边简单演示一下RabbitMQ高可用集群的搭建,附带一个简单使用C#驱动RabbtiMQ集群的小栗子。

1 搭建RabbitMQ高可用集群

  首先准备三台设备,这里采用的三台Centos7的虚拟机,测试一下各个虚拟机能不能相互ping通,如果可以相互ping通的话,在每台虚拟机上分别安装RabbitMQ,可以参考第一篇的安装方法

第1步 修改主机配置

   为了方便机器间的相互访问,三台centos都执行  vim /etc/hosts ,添加下边的配置(注意修改成自己设备的IP):

192.168.70.129 rabbitmq1
192.168.70.131 rabbitmq2
192.168.70.133 rabbitmq3

  一般情况,hosts文件中内容如下:

第2步:修改.erlang.cookie文件

  修改三台设备的.erlang.cookie中的key一致。如果使用的是前边的安装方法,.erlang.cookie的位置为 /var/lib/rabbitmq/.erlang.cookie (采用其他安装方式找不到文件的话,可以使用命令  find / -name '.erlang.cookie' 找到文件位置)。这里三台虚拟机的key都采用192.168.70.129的key(值为CRRQPKHDXEEIUJUOGYKN),在另外两台设备上 执行命令: vim /var/lib/rabbitmq/.erlang.cookie ,修改文件内容为CRRQPKHDXEEIUJUOGYKN。在修改时如果遇到权限问题,可执行命令 chmod 600 /var/lib/rabbitmq/.erlang.cookie 修改文件的权限为可写,修改内容完成后,执行命令 chmod 400 /var/lib/rabbitmq/.erlang.cookie 把文件再次改成只读的。

  完成上边的两步后,erlang集群就搭建好了,重启所有的设备即可。在rabbitmq1节点的虚拟机上执行命令 rabbitmqctl cluster_status 查看集群状态:

第3步:添加/删除节点

添加节点

  把rabbitmq2节点添加到集群中去,在rabbitmq2节点执行以下命令:

rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@rabbit1
rabbitmqctl start_app

  执行完成后,查看集群状态,看到rabbitmq2已经在集群中了,如下:

  重复上边的步骤,把rabbitmq3也添加到集群中,在rabbitmq3节点执行下边命令:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@rabbit2
rabbitmqctl start_app
  查看集群状态,rabbitmq3也在集群中了,如下:  

  这时我们打开任意一个节点的Web管理界面,显示如下,看到集群已经配置完成了:

删除节点
  把某一节点从集群中删除很简单,reset一下节点即可。如删除rabbitmq3节点,在rabbitmq3上执行以下命令:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app

  执行完成后,查看集群状态如下:

  现在搭建的集群是默认的普通集群,普通集群中节点可以共享集群中的exchange,routingKey和queue,但是queue中的消息只保存在首次声明queue的节点中。任意节点的消费者都可以消费其他节点的消息,比如消费者连接rabbitmq1节点的消费者(代码中建立Connection时,使用的rabbitmq1的IP)可以消费节点rabbitmq2的队列myqueue2中的消息,消息传输过程是:rabbitmq2把myqueue2中的消息传输给rabbtimq1,然后rabbitmq1节点把消息发送给consumer。因为queue中的消息只保存在首次声明queue的节点中,这样就有一个问题:如果某一个node节点挂掉了,那么只能等待该节点重新连接才能继续处理该节点内的消息(如果没有设置持久化的话,节点挂掉后消息会直接丢失)。如下图,rabbitmq1节点挂掉后,myqueue队列就down掉了,不能被访问。

  针对上边的问题,我们可能会想到:如果可以让rabbitmq中的节点像redis集群的节点一样,每一个节点都保存所有的消息,比如让rabbitmq1不仅仅保存自己队列myqueue的消息,还保存其他节点的队列myqueue2和myqueue3中的消息,rabbitmq2和rabbitmq3节点也一样,这样就不用担心宕机的问题了。rabbitmq也提供了这样的功能:镜像队列。镜像队列由一个master和多个slave组成,使用镜像队列消息会自动在镜像节点间同步,而不是在consumer取数据时临时拉取。

第4步:配置镜像队列

  rabbitmq配置镜像队列十分简单,我们在任意一个node节点下执行下边的命令就可以完成镜像队列的配置(当然也可以在Web管理界面上添加policy):

rabbitmqctl set_policy ha-all "^my" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
# ha-all:为策略名称;
# ^my:为匹配符,只有一个^代表匹配所有,^abc为匹配名称以abc开头的queue或exchange;
# ha-mode:为同步模式,一共3种模式:
#    ①all-所有(所有的节点都同步消息),
#    ②exctly-指定节点的数目(需配置ha-params参数,此参数为int类型比如2,在集群中随机抽取2个节点同步消息)
#    ③nodes-指定具体节点(需配置ha-params参数,此参数为数组类型比如["rabbit@rabbitmq1","rabbit@rabbitmq2"],明确指定在这两个节点上同步消息)。

  打开Web管理界面,如果效果如下表示镜像队列已经配置完成了。当前myqueue的master节点为rabbitmq1:

  如果首次声明queue的节点(master)挂了,其他节点会自动变成master,如上图myqueue的master为rabbitmq1,停掉rabbtmq1后,结果如下:rabbitmq2成为了master。

  我们发现rabbitmq1节点挂了后,rabbitmq2自动成为了myqueue的master,myqueue不会down掉,可以正常的添加/删除/获取消息,这就解决了普通集群宕机的问题。使用镜像队列,因为各个节点要同步消息,所以比较耗费资源,一般在可靠性比较高的场景使用镜像队列。

还可以配置其他策略的镜像队列,也是一行命令即可完成配置,一些其它同步模式的栗子:

#策略名为ha-twe,匹配以“my”开头的queue或exchange,在集群中随机挑选镜像节点,同步的节点为2个
rabbitmqctl set_policy ha-two "^my" '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'
#策略名为ha-nodes,匹配以“my”开头的queue或exchange,指定rabbit@rabbitmq2和rabbit@rabbitmq3为同步节点
rabbitmqctl set_policy ha-nodes "^my" \ '{"ha-mode":"nodes","ha-params":["rabbit@rabbitmq2", "rabbit@rabbitmq3"]}'

第5步:C#驱动RabbitMQ集群

  C#驱动RabbitMQ集群与C#驱动单机RabbtiMQ的方式基本一样,区别在于使用集群时,创建Connection指定的是一个host集合。看一个简单的栗子:

生产者代码:

        static void Main(string[] args)
{
var factory = new ConnectionFactory()
{
UserName = "wyy",//用户名
Password = "",//密码
AutomaticRecoveryEnabled = true,//Connection断了,自动重新连接
};
//集群中的三个rabbitmq节点
List<string> hosts = new List<string>() { "192.168.70.129", "192.168.70.131", "192.168.70.1233" };
//随机连接一个rabbitmq节点
using (var connection = factory.CreateConnection(hosts))
{
//创建通道channel
using (var channel = connection.CreateModel())
{
Console.WriteLine("生产者准备就绪....");
#region 发布100条消息
for (int i = ; i < ; i++)
{
channel.BasicPublish(exchange: "myexchange",
routingKey: "mykey",
basicProperties: null,
body: Encoding.UTF8.GetBytes($"第{i}条消息"));
}
#endregion
}
}
Console.ReadKey();
}

消费者代码:

        static void Main(string[] args)
{
var factory = new ConnectionFactory()
{
UserName = "wyy",//用户名
Password = "",//密码
};
//集群中的三个rabbitmq节点
List<string> hosts = new List<string>() { "192.168.70.129", "192.168.70.131", "192.168.70.1233" };
//随机连接一个rabbitmq节点
using (var connection = factory.CreateConnection(hosts))
{
using (var channel = connection.CreateModel())
{
//使用Qos,每次接收1条消息
channel.BasicQos(prefetchSize: , prefetchCount: , global: false);
Console.WriteLine("消费者准备就绪....");
#region EventingBasicConsumer //定义消费者
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (sender, ea) =>
{
//处理一条消息需要10s时间
Thread.Sleep();
//显示确认消息
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
Console.WriteLine($"处理消息【{Encoding.UTF8.GetString(ea.Body)}】完成!");
};
//处理消息
channel.BasicConsume(queue: "myqueue",
autoAck: false,
consumer: consumer);
Console.ReadKey();
#endregion
}
}
}

   执行这两个应用程序,结果如下:

  到这里RabbtMQ的集群搭建就告一段落了,有一个小问题:RabbitMQ的集群默认不支持负载均衡的。我们可以根据设备的性能,使用Qos给各个消费者指定合适的最大发送条数,这样可以在一定程度上实现负载均衡。也有园友通过Haproxy实现RabbitMQ集群的负载均衡,有兴趣的小伙伴可以研究一下,为什么使用Haprpxy而不用Ngnix呢?这是因为Haproxy支持四层(tcp,udp等)和七层(http,https,email等)的负载均衡,而Nginx只支持七层的负载均衡,而Rabbitmq是通过tcp传输的。本节也是RabbitMQ系列的最后一篇,如果文中有错误的话,希望大家可以指出,我会及时修改,谢谢。

  

快速掌握RabbitMQ(五)——搭建高可用的RabbitMQ集群的更多相关文章

  1. keepalived工作原理和配置说明 腾讯云VPC内通过keepalived搭建高可用主备集群

    keepalived工作原理和配置说明 腾讯云VPC内通过keepalived搭建高可用主备集群 内网路由都用mac地址 一个mac地址绑定多个ip一个网卡只能一个mac地址,而且mac地址无法改,但 ...

  2. 搭建高可用的MongoDB集群

    http://www.csdn.net/article/2014-04-09/2819221-build-high-avialable-mongodb-cluster-part-1/1 在大数据的时代 ...

  3. 手动搭建高可用的kubernetes 集群

    之前按照和我一步步部署 kubernetes 集群的步骤一步一步的成功的使用二进制的方式安装了kubernetes集群,在该文档的基础上重新部署了最新的v1.8.2版本,实现了kube-apiserv ...

  4. Redis Cluster搭建高可用Redis服务器集群

    一.Redis Cluster集群简介 Redis Cluster是Redis官方提供的分布式解决方案,在3.0版本后推出的,有效地解决了Redis分布式的需求,当一个节点挂了可以快速的切换到另一个节 ...

  5. Redis总结(八)如何搭建高可用的Redis集群

    以前总结Redis 的一些基本的安装和使用,大家可以这这里查看Redis 系列文章:https://www.cnblogs.com/zhangweizhong/category/771056.html ...

  6. 搭建高可用的redis集群,避免standalone模式带给你的苦难

    现在项目上用redis的话,很少说不用集群的情况,毕竟如果生产上只有一台redis会有极大的风险,比如机器挂掉,或者内存爆掉,就比如我们生产环境 曾今也遭遇到这种情况,导致redis内存不够挂掉的情况 ...

  7. MyCAT+MySQL 搭建高可用企业级数据库集群——第2章 MyCat入门

    2-1 章节综述 2-2 什么是MyCat 2-3 什么是数据库中间层 2-4 MyCat的主要作用 2-5 MyCat基本元素 2-6 MyCat的安装 2-1 章节综述 1.掌握Mycat的基础概 ...

  8. MyCAT+MySQL搭建高可用企业级数据库集群视频课程

    原文地址:https://www.guangboyuan.cn/mycatmysql%E6%90%AD%E5%BB%BA%E9%AB%98%E5%8F%AF%E7%94%A8%E4%BC%81%E4% ...

  9. MyCAT+MySQL 搭建高可用企业级数据库集群——第3章 MyCat核心配置讲解

    3-1 章节综述 3-2 常用配置文件间的关系 3-3 server.xml配置详解 3-4 log4j2.xml配置文件 3-5 rule.xml 3-6 常用分片算法(上) 3-7 常用分片算法( ...

随机推荐

  1. .net获取select控件中的文本内容

    .net获取select控件中的文本内容 2009-11-28 21:19小V古 | 分类:C#/.NET | 浏览1374次 <select id="SecType" st ...

  2. ubuntu12.04+kafka2.9.2+zookeeper3.4.5的伪分布式集群安装和demo(java api)测试

    博文作者:迦壹 博客地址:http://idoall.org/home.php?mod=space&uid=1&do=blog&id=547 转载声明:可以转载, 但必须以超链 ...

  3. Bugtags 与其它产品的区别

    如果您刚刚接触 Bugtags,可能心里会有这样的疑问,下面将介绍 Bugtags 与其它的一些产品的区别. Bugtags 不是做统计的 SDK 大家都会在 App 里集成用户数据统计的 SDK,但 ...

  4. Nginx 上的 php-fpm 资源侵占问题

    测试人员向我们反映:在Facebook平台的游戏比其它平台的游戏明显更慢.我询问,是不是因为FQ网络原因.他们说:不是,其它游戏也比较流畅.使用httpwatch查看了http请求,发现api.php ...

  5. hadoop的ganglia数据监控

    如果我们想知道当前运行的hadoop集群的状态,可以通过hadoop的客户端和web页面来获得,但是如果我们想知道当前集群的繁忙程度,如读写次数,这些工具就办不到了.幸运的是hadoop提供了一种ga ...

  6. POJ2192 - Zipper(区间DP)

    题目大意 给定三个字符串s1,s2,s3,判断由s1和s2的字符能否组成字符串s3,并且要求组合后的字符串必须是s1,s2中原来的顺序. 题解 用dp[i][j]表示s1的前i个字符和s2的前j个字符 ...

  7. jetty插件配置

    1.jetty maven 插件启动设置: Base directory:${project_loc} Goals:clean -Djetty.port=8080 jetty:run 2.jetty ...

  8. SVG 学习(一)

    SVG 意为可缩放矢量图形(Scalable Vector Graphics). SVG 使用 XML 格式定义图像. 什么是SVG? SVG 指可伸缩矢量图形 (Scalable Vector Gr ...

  9. (模拟) codeVs1160 蛇形矩阵

    题目描述 Description 小明玩一个数字游戏,取个n行n列数字矩阵(其中n为不超过100的奇数),数字的填补方法为:在矩阵中心从1开始以逆时针方向绕行,逐圈扩大,直到n行n列填满数字,请输出该 ...

  10. OKI系列针式打印机更换色带图解教程

    色带一直换不好,今天找到一个带图的教程,收藏一下 打开新色带的包装后,我们可以仔细观察一下新色带,找到里面带有一段“扭曲”色带的位置,这段色带就是:“莫比乌斯带”结构. 找到“莫比乌斯带”结构(就是有 ...