RabbitMQ 搭建集群

项目搭建集群时可能有这样的需求:

  1. 负载均衡
  2. 任何节点故障 、或者重启将不会影响我们正常使用某个队列

本文旨在解决两个问题。


1. 项目基本搭建

参考链接

2. 几个要点

2.1 什么是集群
Clustering connects multiple machines together to form a single logical broker. 
Communication is via Erlang message-passing, so all nodes in the cluster must have the same Erlang cookie. 
The network links between machines in a cluster **must** be reliable, and all machines in the cluster must run the same versions of RabbitMQ and Erlang.

Virtual hosts, exchanges, users, and permissions are automatically mirrored across all nodes in a cluster. 
Queues may be located on a single node, or mirrored across multiple nodes.
A client connecting to any node in a cluster can see all queues in the cluster, even if they are not located on that node.

Typically you would use clustering for high availability and increased throughput, with machines in a single location.

以上是官方文档给出的解释。
稍稍说几个地方:
1.安装Erlang环境后有一个.erlang.cookie文件,集群中各节点的正常通信就是以cookie的一致性为基础的,所以必须保证集群中所有节点有相同的cookie;一般情况下文件会在/var/lib/rabbitmq/路径下(如果没有请find下),找出一个节点上的文件后复制到各个节点上。
2.集群有两种模式,普通和镜像模式。

集群模式

普通模式:
对于Queue来说,消息实体只存在于其中一个节点,A、B两个节点仅有相同的元数据,即队列结构。
当消息进入A节点的Queue中后,consumer从B节点拉取时,RabbitMQ会临时在A、B间进行消息传输,把A中的消息实体取出并经过B发送给consumer。
所以consumer应尽量连接每一个节点,从中取消息。即对于同一个逻辑队列,要在多个节点建立物理Queue。否则无论consumer连A或B,出口总在A,会产生瓶颈。
该模式存在一个问题就是当A节点故障后,B节点无法取到A节点中还未消费的消息实体。
如果做了消息持久化,那么得等A节点恢复,然后才可被消费;如果没有持久化的话,数据就会丢失掉。

镜像模式:
该模式解决了上述问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在consumer取数据时临时拉取。
该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。

2.2 集群节点

集群中有两种节点:

  • 内存节点:只保存状态到内存(一个例外的情况是:持久的queue的持久内容将被保存到disk)
  • 磁盘节点:保存状态到内存和磁盘

内存节点虽然不写入磁盘,但是它执行比磁盘节点要好。集群中,只需要一个磁盘节点来保存状态就足够了。
如果集群中只有内存节点,那么不能停止它们,否则所有的状态、消息等都会丢失。
详细可见链接

2.3 负载均衡器

关于负载均衡器,商业的比如F5的BIG-IP,Radware的AppDirector,是硬件架构的产品,可以实现很高的处理能力。但这些产品昂贵的价格会让人止步,所以我们还有软件负载均衡方案--互联网公司常用的软件LB一般有LVS、HAProxy、Nginx等。LVS是一个内核层的产品,主要在第四层负责数据包转发,使用较复杂。HAProxy和Nginx是应用层的产品,但Nginx主要用于处理HTTP,所以这里选择HAProxy作为RabbitMQ前端的LB。

haproxy安装

因为当前业务主要是实现RabbitMQ前端的LB,所以只配置和RabbitMQ相关的参数:

defaults 
    mode                    http 
    log                     global 
    option                  httplog 
    option                  dontlognull 
    option http-server-close 
    option forwardfor       except 127.0.0.0/8 
    option                  redispatch 
    retries                 3 
    timeout http-request    10s 
    timeout queue           1m 
    timeout connect         10s 
    timeout client          1m 
    timeout server          1m 
    timeout http-keep-alive 10s 
    timeout check           10s 
    maxconn                 3000
 
listen rabbitmq_cluster 
    bind *:5671
    mode tcp
    balance roundrobin
    server   rqslave1 172.16.3.107:5672 check inter 2000 rise 2 fall 3   
    server   rqslave2 172.16.3.108:5672 check inter 2000 rise 2 fall 3

rqslave1 是172.16.3.107:5672上的节点名称,请严格对应。

check为健康检查指令。
inter 2000表示检察时间间隔为2000毫秒。
rise 2表示检查成功两次即将其标识为可用。
fall 3表示检查失败三次即将其标识为不可用

注:
   负载均衡器会绑定5671端口,且轮询我们的两个节点172.16.3.107、172.16.3.108的5672端口;
这样磁盘节点出了故障也不会影响,除非同时出故障。
   访问的端口需要调整为haproxy所在的机器ip加绑定的端口号,例如172.16.3.108:5761。
2.4 配置策略

使用Rabbit镜像功能,需要基于rabbitmq策略来实现,策略是用来控制和修改集群范围中某个vhost队列行为和Exchange行为。
在cluster中任意节点启用策略,策略会自动同步到集群节点。

# rabbitmqctl set_policy  ha-allqueue "^" '{"ha-mode":"all"}'

这行命令在vhost名称为hrsystem创建了一个策略,策略名称为ha-allqueue,策略模式为 all 即复制到所有节点,包含新增节点,策略中正则表达式 “^” 表示所有匹配的队列名称。
官方set_policy说明参见

3. 总结

1. 设计架构可以如下:在一个集群里,有4台机器,其中1台使用磁盘模式,另2台使用内存模式。
   2台内存模式的节点,无疑速度更快,因此客户端(consumer、producer)连接访问它们。
   而磁盘模式的节点,由于磁盘IO相对较慢,因此仅作数据备份使用,另外一台作为反向代理。

2. 作者在搭建的过程中遇到了很多问题,但回头看看,静下心来大多是可以避免的;
   心平气和地,一步一步地,林深见鹿,海蓝逢鲸。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • 整体架构 部署步骤 基于 Docker 基本概念内存节点只保存状态到内存,例外情况是:持久的 queue 的内容将...
    mvictor阅读 12,755评论 5 30
  • 关于消息队列,从前年开始断断续续看了些资料,想写很久了,但一直没腾出空,近来分别碰到几个朋友聊这块的技术选型,是时...
    预流阅读 584,647评论 51 786
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,652评论 18 139
  • 本文转载自http://dataunion.org/?p=9307 背景介绍Kafka简介Kafka是一种分布式的...
    Bottle丶Fish阅读 5,469评论 0 34
  • 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅的消息系统。主要设计目标如下: 以时间复杂度为O...
    高广超阅读 12,831评论 8 167