RabbitMQ的集群方案有以下几种: 
1.普通的集群 
exchange,buindling再所有的节点上都会保存一份,但是queue只会存储在其中的一个节点上,但是所有的节点都会存储一份queue的meta信息。因为这样有两个好处: 
1)存储空间。如果每一个节点上都有全部的消息,有多少个节点就会有多少个消息总量的copy。加入一个队列的消息占用的空间是1G,那么三个节点就是3G 
2) 性能。消息需要在节点之间传输会有很大的网络开销。如果消息设置了durable即持久化,还会增加很大的磁盘负载 
队列存储的节点取决于,创建队列的客户端当时所连接的节点。如果生产者连接的是另外一个节点,将会把消息转发到存储该队列的节点上。如果消费者连接了非存储队列的节点取数据,者从存储消息的节点拉去数据。所以: 
1)创建队列都连到了一个节点上,所有的队列都存储在一个节点上。 
2)存消息的节点挂掉了,consumer只能等到节点恢复后才能读到消息。 
3)设A,B节点,queue数据在A上:可以向A或B生产或消费消息。但是一旦往B生产消息时A挂了,client是不会收到任何错误信息的并可以继续发送,而实际上消息是被丢弃了。一旦此时client挂了后在连接B会报节点A不存在而失败。在B读也是类似的,在client批量取到的数据读完之前是不会感知A有没有挂掉,等到读取下一批数据时一旦A挂掉会报错。 
所以这种集群方法的特点是: 
1) 高吞吐量 
2)非高可用 

2.镜像模式 
镜像模式和普通模式的区别就是,队列的数据都镜像了一份到所有的节点上。这样任何一个节点失效,不会影响整个集群的使用。 
在实现上,mirror queue内部有一套选举算法,会选出一个master,和若干个slaver。master和slaver 通过相互间不断发送心跳来检查是否连接断开。可以通过指定net_ticktime来控制心跳检查频率。注意一个单位时间net_ticktime实际上做了4次交互,故当超过net_ticktime (± 25%) 秒没有响应的话则认为节点挂掉。另外注意修改net_ticktime时需要所有节点都一致。 
配置举例: 

        {rabbit, [{tcp_listeners, [5672]}]}, 
        {kernel, [{net_ticktime,  120}]} 
]. 
consumer,任意连接一个节点,若连上的不是master,请求会转发给master,为了保证消息的可靠性,consumer回复ack给master后,master删除消息并广播所有的slaver去删除。 
publisher ,任意连接一个节点,若连上的不是master,则转发给master,由master存储并转发给其他的slaver存储。 
如果master挂掉,则从slaver中选择消息队列最长的为master,在这种情况下可以存在消息未同步给ack消息未同步的情况,会造成消息重发(默认是异步同步的)。总共有以下几件事情发生: 

1)1个最老的(队列最长的)的slaver提升为master,如果没有一个slaver是和master同步的则会造成消息丢失。 
2) 要提升为master的slaver会认为以前所有连接挂掉的master的消费者都断开了连接。那么存在clinet发送了ack的消息单还在路上是master挂掉的情况,或者master收到了ack但是在广播给slaver的时候master挂掉的情况,所以新的master别无选择,只能认为消息没有被确认。他会requeue他认为没有ack的消息。那么client可能就收到了重复的消息,并要再次发送ack。 

3)从镜像队列中消费的client支持了consumer Cancellation通知的,将收到通知并订阅的mirrored-queue被取消了,这是因为该mirrored-queue 升级成了master,这是client需要重现去找mirrored-queue上消费,这样就避免了client继续发送ack到老的挂掉的master上。避免收到新的master发送的相同的消息。 
4)如果noAck=true,且在mirrored-queue上消费,那么在切换时由于服务器是先ack然后发送到noAck=true的消费者,这时连接断开可能导致该数据丢失 

如果slaver挂掉,则集群的节点状态没有任何变化。只要client没有连到这个节点上,也不会给client发送失败的通知。在检测到slaver挂掉的期间publish消息会有延迟。如果配置了高可用策略是自动同步,当slaver起来后,队列中有大量的消息需要同步,将会整个集群阻塞长时间的不能读写直到同步结束。 
这两个挂掉的情况都需要客户端镜像容错,比如在连接断开的时候进行重连(官方的Java和.net 客户端提供了callback方法在监听到链接失败的时候调用。Java在Connection和channel类中提供了ShutdownListener 的callback方法,.net client在IConnecton中提供了ConnectionShuedown在Imodel中提供了ImodelShutdown事件供调用) 。也可以在client和server之间加入LoadBalancer.比如haproxy做负载均衡。 

指定mirror策略: 
有三种策略: 
all:队列将mirrored到所有集群中的节点中,当新节点添加进来时也会mirrored到新的节点 
exactly(需指定count):如果节点数小于count数,则队列将mirrored到所有的节点。如果节点数大于count,新的节点将不再创建队列的mirror(即使原来已创建mirror的节点挂掉也不会创建) 
nodes:对指定的节点进行mirror。如果没有一个指定的节点在运行中,那么只有client连接的那个节点才会声明queue(这里有个迁移策略:假如queue是在[A,B]上且A为master,若给定的新的策略为nodes[C,D],那么为了防止数据丢失,在迁移中会同时存在[A,C,D]直到C,D已经同步好以后,A才会关闭) 
配置举例: 
设置queue的名称为ha.的为高可用: 
linux:rabbitmqctl set_policy ha-all "^ha\." '{"ha-mode":"all"}' 
win:rabbitmqctl set_policy ha-all "^ha\." "{""ha-mode"":""all""}" 
http api:PUT /api/policies/%2f/ha-all {"pattern":"^ha\.", "definition":{"ha-mode":"all"}} 
web ui: 
1:Navigate to Admin > Policies > Add / update a policy. 
2:Enter "ha-all" next to Name, "^ha\." next to Pattern, and "ha-mode" = "all" in the first line next to Policy. 
3:Click Add policy. 
举例2: 
rabbitmqctl set_policy ha-two "^two\." \ 
   '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}' 

自动或手动同步: 
你可以查看哪些slave已经同步好了: 
rabbitmqctl list_queues name slave_pids synchronised_slave_pids 
你可以手动同步(默认手动同步): 
rabbitmqctl sync_queue name 
你可以取消自动同步: 
rabbitmqctl cancel_sync_queue name 
一个没有同步的mirror,它仍然会同步后续插入队列的数据,但是队列前面的数据却没有。但是随着队列的不断消费,导致空缺的部分的消息被消费掉了,此时mirror也可以是同步了的。 

3.主备集群 
主备方式(active,passive)只有一个节点处于服务状态,可以结合pacemaker和ARBD, 
shovel简单从一个broker的一个队列中消费消息,且转发该消息到另一个broker的交换机。 
这种方式用的比较少,这里就不做介绍了。详见http://www.rabbitmq.com/pacemaker.html

RabbitMQ高可用方案总结的更多相关文章

  1. 1.rabbitmq高可用方案

    采用标准集群模式  HAPROXY + rabbitmq 2个 ram  和  一个 disk 节点 主机规划: 192.168.157.128 haproxy keepalive 主 ram节点 1 ...

  2. rabbitMQ高可用方案

    普通模式 默认的集群模式,以两个节点(rabbit01.rabbit02)为例来进行说明.对于Queue来说,消息实体只存在于其中一个节点rabbit01(或者rabbit02),rabbit01和r ...

  3. RabbitMQ学习系列(六): RabbitMQ 高可用集群

    前面讲过一些RabbitMQ的安装和用法,也说了说RabbitMQ在一般的业务场景下如何使用.不知道的可以看我前面的博客,http://www.cnblogs.com/zhangweizhong/ca ...

  4. Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群

    Redis总结(五)缓存雪崩和缓存穿透等问题   前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...

  5. MySQL高可用方案

    高可用架构对于互联网服务基本是标配,无论是应用服务还是数据库服务都需要做到高可用.虽然互联网服务号称7*24小时不间断服务,但多多少少有一些时候服务不可用,比如某些时候网页打不开,百度不能搜索或者无法 ...

  6. [转]MYSQL高可用方案探究(总结)

    前言 http://blog.chinaunix.net/uid-20639775-id-3337432.htmlLvs+Keepalived+Mysql单点写入主主同步高可用方案 http://bl ...

  7. Sentinel-Redis高可用方案(一):主从复制

    引言 大概是因为Redis是个人开发的产品,所以Redis的高可用方案是被分成了几块来实现:主从复制.主从切换以及虚拟IP或客户端方案. 从Redis 2.8开始加入对Sentinel机制从而实现了服 ...

  8. Redis之高可用方案

    Redis之高可用方案   Redis以其高效的访问速度著称.但由于官方还未发布redis-cluster,而redis的replica又有诸多不便:比如一组master-slave的机器,如果之间有 ...

  9. mysql高可用方案总结性说明

    MySQL的各种高可用方案,大多是基于以下几种基础来部署的(也可参考:Mysql优化系列(0)--总结性梳理   该文后面有提到)1)基于主从复制:2)基于Galera协议(PXC):3)基于NDB引 ...

随机推荐

  1. PHP 生成PDF

    一个项目中需要用到网页生成PDF,就是将整个网页生成一个PDF文件, 以前也用过HTML2PDF,只能生成一些简单的HTML代码,复杂的HTML + css 生成的效果惨不忍睹, 百度了一下,发现有个 ...

  2. jsp标签<c:forEach>取出传递参数注意

    运行书里的代码,其中servlet可以通过以下两个方式向jsp传参数: 1.         request.getSession().setAttribute("productList&q ...

  3. 掌握Thinkphp3.2.0----标签库

    1.什么是内置标签?什么是标签扩展库? Cx.class.php 和 Html.class.php 2.怎么加载非内置标签,怎么使用? 两种方式加载 3.怎么扩展自定义的标签? 仿照Html.clas ...

  4. SSH登录远程主机执行脚本找不到环境变量

    这是因为在Linux上,bash会有四种模式,根据不同的case,Linux会加载不同模式的bash.一般如果你自己直接登录主机,能看到环境变量,但是使用ssh 远程登录执行脚本就找不到环境变量,那么 ...

  5. Struts2与Ajax的整合

    整合: 导入jar包 sturts2-json-plugin-2.1.8.1.jar 说明: 在该jar包中有struts-plugin.xml文件 <struts>            ...

  6. 数据库 定义 bit 类型 (true=1,false=0)

    当Sql Server数据库定义 数据 为 bit 类型时, 编写代码时 要用 true or false 赋值. 例如: OffTheShelf  定义类型为  bit 后台赋值时 OffTheSh ...

  7. oracle数据库连接慢的问题

    1.现象 工程为spring+mybatis+xfire,webservice工程服务,实现的接口数据功能 2.修复方法 经过各种尝试: 1.重新部署工程     无果 2.重新部署tomcat   ...

  8. ORA-29275: partial multibyte character

    查询表报错 修改方式1 和字符集存储方式有关系 ,修改客户端和服务器的字符集存储方害死 修改方式2 修改表的字段由nvarchar2修改为varchar2

  9. python 的var_dump

    from __future__ import print_function from types import NoneType __author__ = "Shamim Hasnath&q ...

  10. 使用HTML5技术控制电脑或手机上的摄像头

    移动设备和桌面电脑上的客户端API起初并不是同步的.最初总是移动设备上先拥有某些功能和相应的API,但慢慢的,这些API会出现在桌面电脑上.其中一个应用接口技术就是getUserMedia API,它 ...