RabbitMQ 搭建集群

項目搭建集群時可能有這樣的需求:

  1. 負載均衡
  2. 任何節(jié)點故障 、或者重啟將不會影響我們正常使用某個隊列

本文旨在解決兩個問題。


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環(huán)境后有一個.erlang.cookie文件,集群中各節(jié)點的正常通信就是以cookie的一致性為基礎(chǔ)的,所以必須保證集群中所有節(jié)點有相同的cookie;一般情況下文件會在/var/lib/rabbitmq/路徑下(如果沒有請find下),找出一個節(jié)點上的文件后復(fù)制到各個節(jié)點上。
2.集群有兩種模式,普通和鏡像模式。

集群模式

普通模式:
對于Queue來說,消息實體只存在于其中一個節(jié)點,A、B兩個節(jié)點僅有相同的元數(shù)據(jù),即隊列結(jié)構(gòu)。
當消息進入A節(jié)點的Queue中后,consumer從B節(jié)點拉取時,RabbitMQ會臨時在A、B間進行消息傳輸,把A中的消息實體取出并經(jīng)過B發(fā)送給consumer。
所以consumer應(yīng)盡量連接每一個節(jié)點,從中取消息。即對于同一個邏輯隊列,要在多個節(jié)點建立物理Queue。否則無論consumer連A或B,出口總在A,會產(chǎn)生瓶頸。
該模式存在一個問題就是當A節(jié)點故障后,B節(jié)點無法取到A節(jié)點中還未消費的消息實體。
如果做了消息持久化,那么得等A節(jié)點恢復(fù),然后才可被消費;如果沒有持久化的話,數(shù)據(jù)就會丟失掉。

鏡像模式:
該模式解決了上述問題,其實質(zhì)和普通模式不同之處在于,消息實體會主動在鏡像節(jié)點間同步,而不是在consumer取數(shù)據(jù)時臨時拉取。
該模式帶來的副作用也很明顯,除了降低系統(tǒng)性能外,如果鏡像隊列數(shù)量過多,加之大量的消息進入,集群內(nèi)部的網(wǎng)絡(luò)帶寬將會被這種同步通訊大大消耗掉。

2.2 集群節(jié)點

集群中有兩種節(jié)點:

  • 內(nèi)存節(jié)點:只保存狀態(tài)到內(nèi)存(一個例外的情況是:持久的queue的持久內(nèi)容將被保存到disk)
  • 磁盤節(jié)點:保存狀態(tài)到內(nèi)存和磁盤

內(nèi)存節(jié)點雖然不寫入磁盤,但是它執(zhí)行比磁盤節(jié)點要好。集群中,只需要一個磁盤節(jié)點來保存狀態(tài)就足夠了。
如果集群中只有內(nèi)存節(jié)點,那么不能停止它們,否則所有的狀態(tài)、消息等都會丟失。
詳細可見鏈接。

2.3 負載均衡器

關(guān)于負載均衡器,商業(yè)的比如F5的BIG-IP,Radware的AppDirector,是硬件架構(gòu)的產(chǎn)品,可以實現(xiàn)很高的處理能力。但這些產(chǎn)品昂貴的價格會讓人止步,所以我們還有軟件負載均衡方案--互聯(lián)網(wǎng)公司常用的軟件LB一般有LVS、HAProxy、Nginx等。LVS是一個內(nèi)核層的產(chǎn)品,主要在第四層負責數(shù)據(jù)包轉(zhuǎn)發(fā),使用較復(fù)雜。HAProxy和Nginx是應(yīng)用層的產(chǎn)品,但Nginx主要用于處理HTTP,所以這里選擇HAProxy作為RabbitMQ前端的LB。

haproxy安裝

因為當前業(yè)務(wù)主要是實現(xiàn)RabbitMQ前端的LB,所以只配置和RabbitMQ相關(guān)的參數(shù):

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上的節(jié)點名稱,請嚴格對應(yīng)。

check為健康檢查指令。
inter 2000表示檢察時間間隔為2000毫秒。
rise 2表示檢查成功兩次即將其標識為可用。
fall 3表示檢查失敗三次即將其標識為不可用

注:
   負載均衡器會綁定5671端口,且輪詢我們的兩個節(jié)點172.16.3.107、172.16.3.108的5672端口;
這樣磁盤節(jié)點出了故障也不會影響,除非同時出故障。
   訪問的端口需要調(diào)整為haproxy所在的機器ip加綁定的端口號,例如172.16.3.108:5761。
2.4 配置策略

使用Rabbit鏡像功能,需要基于rabbitmq策略來實現(xiàn),策略是用來控制和修改集群范圍中某個vhost隊列行為和Exchange行為。
在cluster中任意節(jié)點啟用策略,策略會自動同步到集群節(jié)點。

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

這行命令在vhost名稱為hrsystem創(chuàng)建了一個策略,策略名稱為ha-allqueue,策略模式為 all 即復(fù)制到所有節(jié)點,包含新增節(jié)點,策略中正則表達式 “^” 表示所有匹配的隊列名稱。
官方set_policy說明參見。

3. 總結(jié)

1. 設(shè)計架構(gòu)可以如下:在一個集群里,有4臺機器,其中1臺使用磁盤模式,另2臺使用內(nèi)存模式。
   2臺內(nèi)存模式的節(jié)點,無疑速度更快,因此客戶端(consumer、producer)連接訪問它們。
   而磁盤模式的節(jié)點,由于磁盤IO相對較慢,因此僅作數(shù)據(jù)備份使用,另外一臺作為反向代理。

2. 作者在搭建的過程中遇到了很多問題,但回頭看看,靜下心來大多是可以避免的;
   心平氣和地,一步一步地,林深見鹿,海藍逢鯨。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 整體架構(gòu) 部署步驟 基于 Docker 基本概念內(nèi)存節(jié)點只保存狀態(tài)到內(nèi)存,例外情況是:持久的 queue 的內(nèi)容將...
    mvictor閱讀 12,902評論 5 30
  • 關(guān)于消息隊列,從前年開始斷斷續(xù)續(xù)看了些資料,想寫很久了,但一直沒騰出空,近來分別碰到幾個朋友聊這塊的技術(shù)選型,是時...
    預(yù)流閱讀 586,573評論 51 787
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 本文轉(zhuǎn)載自http://dataunion.org/?p=9307 背景介紹Kafka簡介Kafka是一種分布式的...
    Bottle丶Fish閱讀 5,581評論 0 34
  • 背景介紹 Kafka簡介 Kafka是一種分布式的,基于發(fā)布/訂閱的消息系統(tǒng)。主要設(shè)計目標如下: 以時間復(fù)雜度為O...
    高廣超閱讀 13,042評論 8 167

友情鏈接更多精彩內(nèi)容