[Open Source] RabbitMQ 高可用叢集方案

Never、C發表於2017-05-22

簡介

RabbitMQ是用erlang開發的,叢集非常方便,因為erlang天生就是一門分散式語言,但其本身並不支援負載均衡。
Rabbit模式大概分為以下三種:單一模式、普通模式、映象模式

RabbitMQ工作模式

  • 單一模式 (最簡單的情況,非叢集模式)

  • 普通模式 (預設的叢集模式)

    • 流程
      • 對於Queue來說,訊息實體只存在於其中一個節點,A、B兩個節點僅有相同的後設資料,即佇列結構。
      • 當訊息進入A節點的Queue中後,consumer從B節點拉取時,RabbitMQ會臨時在A、B間進行訊息傳輸,把A中的訊息實體取出並經過B傳送給consumer。
    • 問題
      • 該模式存在一個問題就是當A節點故障後,B節點無法取到A節點中還未消費的訊息實體。
      • 如果做了訊息持久化,那麼得等A節點恢復,然後才可被消費;如果沒有持久化的話,然後就沒有然後了
  • 映象模式

    • 流程
      • 把需要的佇列做成映象佇列,存在於多個節點,屬於RabbitMQ的HA方案。
      • 訊息實體會主動在映象節點間同步,而不是在consumer取資料時臨時拉取。
    • 問題
      • 降低系統效能
      • 叢集頻寬大大消耗(如果映象佇列數量過多,加之大量的訊息進入)
    • 優點
      • 對可靠性要求較高的場合中適用
  • 叢集說明

    • 一個rabbitmq集 群中可以共享 user,vhost,queue,exchange等,所有的資料和狀態都是必須在所有節點上覆制的

叢集搭建

  • 操作步驟(node1為主,node2,node3為從,node4為proxy)
    • 在 192.168.0.1(node1)、192.168.0.2(node2)、192.168.0.3(node3) 三個節點上安裝,然後開啟 RabbitMQ 監控外掛
    • node1
      • .erlang.cookie檔案複製到 node2、node3
    • node1,node2,node3
      • rabbitmqctl stop // 停止Rabbit
      • rabbitmq-server -detached //
    • node2,node3
      • rabbitmqctl stop
      • rabbitmqctl join_cluster rabbit@node1
      • rabbitmqctl start_app
    • node4
      • 作為proxy指向node1,node2,node3(用於透明呼叫使用)
      • 當然,你也可以透過var connection = factory.CreateConnection(["ip1","ip2"].ToList());
    • cli
      • rabbitmqctl cluster_status // 檢查叢集狀態
      • rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}' // 新增策略
    • gui(如果cli不方便的話)

說明

  • proxy 層可用nginx haproxy nlb lvs

  • 叢集搭建完,任意一臺Rabbit伺服器(節點)掛了,都能正常取到資料。保證了高可用。

  • 順便推薦下自己封裝的Rabbit(Install-Package RabbitMQ.Wrapper)

    • 自動重連
    • 自定義配置
    • 持久化訊息

相關文章