10_RabbitMQ集群搭建

@Author Jacky Wang

近日搭建了RabbitMQ集群,特记录与此.转载请标注出处//www.greatytc.com/p/01527d177e12

一、前提

  • erlang安装版本一致
  • RabbitMQ安装版本一致
  • 下面的例子以192.168.73.134与192.168.73.135为服务器搭建Rabbitmq集群.

二、RabbitMQ集群

RabbitMQ是用erlang开发的,集群非常方便,因为erlang天生就是一门分布式语言,但其本身并不支持负载均衡。Rabbit模式大概分为以下三种:单一模式、普通模式、镜像模式。

  • 单一模式:最简单的情况,非集群模式。

  • 普通模式:默认的集群模式。

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

      该模式解决了上述问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在consumer取数据时临时拉取。
      
      该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。
      
      所以在对可靠性要求较高的场合中适用(后面会详细介绍这种模式,目前我们搭建的环境属于该模式)。
    

2.1 集群中的基本概念

RabbitMQ的集群节点包括内存节点、磁盘节点。

顾名思义内存节点就是将所有数据放在内存,磁盘节点将数据放在磁盘。不过,如前文所述,如果在投递消息时,打开了消息的持久化,那即使是内存节点,数据还是安全的放在磁盘。

一个RabbitMQ集群中可以共享user、vhost、queue、exchange等,所有的数据和状态都是必须在所有节点上复制的,一个例外是那些当前只属于创建它的节点的消息队列,尽管它们可见且可被所有节点读取。RabbitMQ节点可以动态地加入到集群中,一个节点它可以加入到集群中,也可以从集群环集群进行一个基本的负载均衡。

集群中有两种节点:

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

  • 磁盘节点:保存状态到内存和磁盘。

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

思路:
那么具体如何实现RabbitMQ高可用,我们先搭建一个普通集群模式,在这个模式基础上再配置镜像模式实现高可用,Rabbit集群前增加一个反向代理,生产者、消费者通过反向代理访问RabbitMQ集群。

架构图如下:

02.png

2.2 集群模式配置

step1: 局域网配置
在安装好的三台节点服务器中,分别修改/etc/hosts文件
1. vim /etc/hosts

192.168.73.134 node1
192.168.73.135 node2
step2: 设置不同节点间同一认证的Erlang Cookie
Erlang的集群中各节点是通过一个magic cookie来实现的,这个cookie存放在 /var/lib/rabbitmq/.erlang.cookie 中,文件是400的权限。
所以必须保证各节点cookie保持一致,否则节点之间就无法通信。
采用从主节点copy的方式保持Cookie的一致性:

1. chmod 777  /var/lib/rabbitmq/.erlang.cookie
2. scp -p 22 /var/lib/rabbitmq/.erlang.cookie root@192.168.73.135:/var/lib/rabbitmq/

复制好后查看文件所属用户和组以及权限是否满足要求,不满足则修改。之后还原.erlang.cookie的权限,否则可能会遇到错误:
3. chown rabbitmq:rabbitmq .erlang.cookie
4. chmod 400 /var/lib/rabbitmq/.erlang.cookie
step3: 使用 -detached运行各节点
设置好cookie后将各个节点的RabbitMQ重启:
1. cd /sbin
2. rabbitmqctl stop
3. rabbitmq-server start

这里正常重启可能会提示该节点示例已经再运行中。如果出现使用以下命令启动:
1. ps -aux | grep erl
2. kill -9 {pid}
3. RABBITMQ_NODE_PORT=5678 RABBITMQ_NODENAME=rabbit@node1 ./rabbitmq-server -detached
    RABBITMQ_NODE_PORT=5678 RABBITMQ_NODENAME=rabbit@node2 ./rabbitmq-server -detached

ps:上面5678是因为在安装时将rabbitmq的端口修改为5678了,而nodename与hosts里面设置的保持一致。
    依次启动所有节点。
step4: 查看各节点的状态
1. 查看启动端口:  netstat -lntp 

    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 0.0.0.0:4369            0.0.0.0:*               LISTEN      27321/epmd          
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      760/sshd            
    tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1066/master         
    tcp        0      0 0.0.0.0:15678           0.0.0.0:*               LISTEN      27862/beam.smp      
    tcp        0      0 0.0.0.0:25672           0.0.0.0:*               LISTEN      27862/beam.smp      
    tcp6       0      0 :::5678                 :::*                    LISTEN      27862/beam.smp      
    tcp6       0      0 :::8080                 :::*                    LISTEN      964/java            
    tcp6       0      0 :::4369                 :::*                    LISTEN      27321/epmd          
    tcp6       0      0 :::22                   :::*                    LISTEN      760/sshd            
    tcp6       0      0 ::1:25                  :::*                    LISTEN      1066/master         
    tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      964/java            
    tcp6       0      0 :::8009                 :::*                    LISTEN      964/java

2. 查看rabbitmq启动状态:  
    rabbitmqctl -n rabbit1@node1 status
    rabbitmqctl -n rabbit1@node2 status  

3. 访问http://192.168.73.134:15678查看是否可以访问rabbitmq的web管理后台(安装时必须开启)
step5: 创建并部署集群
将rabbit@rabbitmq2与rabbit@rabbitmq1组成集群,且rabbitmq2作为内存节点(硬盘节点有一个即可);

rabbitmq2:
    1. 停止节点2的应用程序:  rabbitmqctl -n rabbit@node2 stop_app
            Stopping rabbit application on node rabbit@rabbitmq2

    2. 作为内存节点加入节点1: rabbitmqctl -n rabbit@node2 join_cluster --ram rabbit@node1
            Clustering node rabbit@node2 with rabbit@node1

    3. 启动节点2的应用程序:  rabbitmqctl -n rabbit@node2 start_app
            Starting node rabbit@node2
step5: 查看集群状态
1.查看节点1的集群状态:   rabbitmqctl -n rabbit@node1 cluster_status
        Cluster status of node rabbit@node1
        [{nodes,[{disc,[rabbit@node1]},{ram,[rabbit@node2]}]},
         {running_nodes,[rabbit@node1]},
         {cluster_name,<<"rabbit@node1">>},
         {partitions,[]},
         {alarms,[{rabbit@node1,[]}]}] 
2. 查看节点2的集群状态:  rabbitmqctl -n rabbit@node2 cluster_status
        Cluster status of node rabbit@node2
        [{nodes,[{disc,[rabbit@node1]},{ram,[rabbit@node2]}]},
         {alarms,[{rabbit@node1,[]}]}]

3. 后台查看集群状态:
06.png
至此,rabbitmq集群搭建完毕。

三、RabbitMQ镜像模式

上面配置RabbitMQ默认集群模式,但并不保证队列的高可用性,尽管交换机、绑定这些可以复制到集群里的任何一个节点,但是队列内容不会复制,虽然该模式解决一部分节点压力,但队列节点宕机直接导致该队列无法使用,只能等待重启,所以要想在队列节点宕机或故障也能正常使用,就要复制队列内容到集群里的每个节点,需要创建镜像队列。

step1:增加负载均衡器

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

1. 安装HAProxy(在192.168.73.136上安装HAProxy)
    yum -y install haproxy

2. 修改haproxy.config配置
    vim /etc/haproxy/haproxy.config
    在其中增加以下配置:
    listen rabbitmq_cluster 0.0.0.0:5678
        mode tcp
        balance roundrobin
        server rabbitmaster 192.168.73.134:5678 check inter 2000 rise 2 fall 3
        server rabbitslave 192.168.73.135:5678 check inter 2000 rise 2 fall 3

修改完HaProxy配置之后重新启动可能会提示绑定端口失败,此时执行以下命令即可:

    setsebool -P haproxy_connect_any=1

负载均衡器会监听192.168.73.136的5678端口,轮询我们的两个节点192.168.73.134、192.168.73.135的5678端口,这样磁盘节点除了故障也不会影响,除非同时出故障。

step2:配置Rabbitmq策略

在任意一个节点上执行:

    rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
    上面的命令会将所有队列设置为镜像队列,即队列会被复制到各个节点,各个节点状态保持一致
step3:使用负载服务器发送消息

客户端使用负载服务器172.16.3.110 (panyuntao3)发送消息,队列会被复制到所有节点。到这里我们完成了RabbitMQ集群的高可用配置。

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