1. 程式人生 > >RabbitMQ入門教程(十四):RabbitMQ單機叢集搭建

RabbitMQ入門教程(十四):RabbitMQ單機叢集搭建

叢集簡介

理解叢集先理解一下元資料

  • 佇列元資料:佇列的名稱和宣告佇列時設定的屬性(是否持久化、是否自動刪除、佇列所屬的節點)
  • 交換機元資料:交換機的名稱、型別、屬性(是否持久化等)
  • 繫結元資料:一張簡單的表格展示瞭如何將訊息路由到佇列。包含的列有 交換機名稱、交換機型別、路由鍵、佇列名稱等
  • vhost元資料:為vhost內佇列、交換機和繫結提供名稱空間和安全屬性

一個佇列的完整內容包括佇列的元資料和佇列的內容
這裡寫圖片描述

繫結表類似於下圖
這裡寫圖片描述

單節點RabbitMQ

這裡寫圖片描述

Rabbit叢集的四種方式:單主叢集、普通叢集、映象叢集、主從叢集

Erlang的叢集是通過Erlang cookie(.erlang.cookie檔案)的方式來允許互相通訊

  • 單機叢集:就是在一臺物理機器上啟動多個節點,每個節點作為作為叢集的一部分。此種方式只適合在學習的時候玩一下,或者在驗證在生產環境中出現特殊情況的現象,在實際情況下不會使用單機叢集,因為如果伺服器宕機了整個伺服器將完全不能再使用。

  • 普通叢集:這裡指的每臺物理機器作為一個節點,此種模式訊息只存在其中一個節點上,叢集中的其他節點僅有相同的元資料(即佇列元資料),當擁有訊息的節點宕機了,那麼其他節點就無法獲取故障節點中尚未消費的訊息,如果故障節點使用了持久化,那隻能等故障節點恢復後才能從該節點上的佇列進行消費,如果沒有持久化,那麼所有訊息將丟失。例如消費者A連線到節點1,但是佇列內容並不在節點1上,可以通過消費者所消費的佇列找到該隊裡所在的節點,然後從該節點上獲取訊息,返回給消費者。
    這裡寫圖片描述

  • 映象叢集:與普通叢集不同,映象叢集會把對壘結構和訊息都同步到每個節點。該模式的好處就是隨便連線到哪個節點都能獲取到訊息,壞處是,當佇列數量很多,訊息也很多的時候,叢集內部的網路頻寬將會被這種同步通訊大量的消耗掉,此種模式用於可靠性要求較高的場合中。

  • 主從叢集warren: 是指一對主備獨立伺服器,並設定一臺負載均衡器來處理故障轉移,使用HAproxy設定備用伺服器很簡單,使用backup來標記一下,只有當主伺服器不可用時才使用備用伺服器。

// 每5秒對伺服器進行健康檢查,後臺伺服器失敗3次之後被認為不可用,也就是15秒後消費者會連線到備用伺服器
server rabbit   127.0
.0.1:5672 check inter 5000 rise 2 fall 3 server rabbit1 127.0.0.1:5673 backup check inter 5000 rise 2 fall 3

這裡寫圖片描述

記憶體節點RAM和磁碟節點disk

  • 記憶體節點:將所有的佇列、交換機、繫結、使用者、許可權、vhost的元資料都儲存在記憶體中 。記憶體節點更快
  • 磁碟節點:將資料存放在磁碟上。磁碟節點需要儲存叢集的配置資訊

單節點系統只允許磁碟節點,否則每次重啟所有資料將會丟失。 一個叢集至少有一個節點是磁碟節點,其他節點可以都是記憶體節點,當節點加入或者離開叢集時都要將變更通知到至少一個磁碟節點。實際使用時至少要兩個磁碟節點,原因是如果只有一個磁碟節點,恰巧磁碟節點崩潰了,那麼RabbitMQ將不能建立佇列、建立交換機、建立繫結、新增使用者、更改許可權、新增或刪除節點等操作,可以正常的釋出和消費訊息。 在實際使用經常將叢集的配置放到磁碟節點上來儲存。

這裡寫圖片描述

單機叢集搭建詳細步驟

第一步:為每個節點配置節點名稱和埠號

  • 配置第一個節點
// 啟動第一個節點,節點名稱為[email protected]
// MacOSX是我的機器名,這裡可以改成自己的機器名或者用localhost
RABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=rabbit@MacOSX rabbitmq-server

這裡寫圖片描述

  • 配置第二個節點
// 啟動第二個節點, 節點名稱為[email protected],這裡使用-detached後臺模式啟動
RABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15673}] -rabbitmq_stomp tcp_listeners [61614] -rabbitmq_mqtt  tcp_listeners [1884]" RABBITMQ_NODENAME=rabbit1 rabbitmq-server -detached

這裡寫圖片描述

  • 配置第三個節點
// 啟動第三個節點,節點名稱為[email protected]
RABBITMQ_NODE_PORT=5674 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15674}] -rabbitmq_stomp tcp_listeners [61615] -rabbitmq_mqtt tcp_listeners [1885]" RABBITMQ_NODENAME=rabbit2 rabbitmq-server -detached

這裡寫圖片描述

  • 所有節點啟動成功後可以登入RabbitMQ Management看一下

這裡寫圖片描述

這裡寫圖片描述

第二步:將rabbit1加入到rabbit中

// 加入叢集時可以指定是磁碟模式還是記憶體模式,預設是disk,可以通過--ram來指定
rabbitmqctl -n rabbit1@MacOSX stop_app
rabbitmqctl -n rabbit1@MacOSX reset
rabbitmqctl -n rabbit1@MacOSX join_cluster rabbit@MacOSX
rabbitmqctl -n rabbit1@MacOSX start_app

這裡寫圖片描述

這裡寫圖片描述

// 檢視指定節點的狀態 
rabbitmqctl status -n rabbit1

第三步:將rabbit2加入到rabbit中

rabbitmqctl -n rabbit2@MacOSX stop_app
rabbitmqctl -n rabbit2@MacOSX reset
rabbitmqctl -n rabbit2@MacOSX join_cluster rabbit@MacOSX --ram
rabbitmqctl -n rabbit2@MacOSX start_app

// 檢視叢集的狀態
rabbitmqctl cluster_status -n rabbit@MacOSX

這裡寫圖片描述

這裡寫圖片描述

HAProxy負載均衡

這裡寫圖片描述

這裡寫圖片描述

1. 安裝

brew install haproxy 

// 檢視haproxy版本
haproxy -version

2. 配置haproxy.cfg

在usr/local/Cellar/haproxy/目錄下建立haproxy.cfg檔案,並進行配置( 如果要使用warren方式,要配置成主備模式只需要在備用伺服器上使用backup標記一下即可)

global
    log 127.0.0.1 local0 info #[日誌輸出配置,所有日誌都記錄在本機,通過local0輸出]
    maxconn 4096 #預設最大連線數,需考慮ulimit-n限制

defaults    # 預設負載均衡配置
    log global
    mode tcp #預設的模式mode { tcp|http|health },tcp是4層,http是7層,health只會返回OK
    option tcplog
    option dontlognull      #不記錄健康檢查日誌資訊
    retries 3               #三次連線失敗就認為是伺服器不可用,也可以通過後面設定
    option abortonclose     #當伺服器負載很高的時候,自動結束掉當前佇列處理比較久的連結
    maxconn 2000            #預設的最大連線數
    timeout connect 5000ms  #連線超時
    timeout client 12000ms  #客戶端超時
    timeout server 12000ms  #伺服器超時

listen rabbitmq_local_cluster 
    mode tcp 
    bind 127.0.0.1:5670  # 前端IP, 供消費者和生產者使用
    balance roundrobin   # 負載均衡方式, 輪詢方式
    server rabbit   127.0.0.1:5672 check inter 5000 rise 2 fall 3
    server rabbit1  127.0.0.1:5673 check inter 5000 rise 2 fall 3
    server rabbit2  127.0.0.1:5674 check inter 5000 rise 2 fall 3

# 資料統計頁面
listen private_monitoring    
    mode http
    bind 127.0.0.1:8100
    option httplog
    stats enable
    stats uri /stats
    stats refresh 5s

3. 啟動HAProxy

/usr/local/Cellar/haproxy/1.8.1/bin/haproxy -f /usr/local/Cellar/haproxy/haproxy.cfg

這裡寫圖片描述

public class Consumer1 {
    @Test
    public void testBasicConsumer1() throws Exception{
        ConnectionFactory factory = new ConnectionFactory();
        factory.setVirtualHost("/");
        // ip和port為HAProxy的地址和埠
        factory.setHost("127.0.0.1");
        factory.setPort(5670);  
        factory.setUsername("guest");
        factory.setPassword("guest");

        Connection connection = factory.newConnection();
        final Channel channel = connection.createChannel();
        String EXCHANGE_NAME = "exchange.direct";
        String QUEUE_NAME = "queue_name";
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "key");

        Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println(message);

            }
        };

        channel.basicConsume(QUEUE_NAME, true, consumer);
        Thread.sleep(100000);
    }
}

常見錯誤

在叢集中,在使用rabbitmqctl命令時經常會報錯,在使用rabbitmqctl命令時,首先會啟動erlang叢集,而erlang叢集需要保證.erlang.cookie內容保持一致,此時如果cookie不一致,會導致rabbitmqctl命令報錯;rabbitmqctl還會啟動erlang的mnesia資料庫,而資料在啟動時會查詢一個和主機名相同的schema, 所以要保證這個schema的名字和當前主機名字保持一致,如果不一致mnesia資料庫就啟動不起來,就會導致rabbitmqctl報錯,所以解決rabbitmqctl報錯可以從兩方面入手,一是cookie值是否相同,二是主機名是否和mnesia的schema是否相同。

  • Error: unable to connect to node [email protected]: nodedown
  • ERROR: node with name “rabbit” already running on “localhost”

首先檢查cookie值是否相同:首先確認一下報錯時會顯示cookie hash:xxxxx的值是否和~/.erlang.cookie檔案中的內容是否一致,如果不一致將報錯提示的cookie hash值覆蓋掉~/.erlang.cookie的內容,注意.erlang.cookie可能沒有修改許可權,需要先修改一下檔案的許可權chmod 777 .erlang.cookie (我就是用這種方式解決的)。

檢查主機名是否和mnesia中的schema的名字是否一致,注意檢視/usr/local/var/log/rabbitmq/[email protected]<.log 這個日誌檔案,日誌中會列印啟動的一些引數,如mnesia的目錄位置,我的位置是/usr/local/var/lib/rabbitmq/mnesia/[email protected],如果不一致,將自己機器的主機名改成mnesia中的名字,好像直接刪除mnesia中子目錄的所有檔案也能解決問題, 在rabbitmq-env.conf中發現了一個配置節點名字的配置[email protected] , 在使用rabbitmqctl命令時經常報主機名稱不匹配,估計和這有很大的關係。在單機模式下建立叢集,建議別使用主機名了,使用localhost代替主機名,估計會減少問題的發生。

rabbitmq啟動日誌

=INFO REPORT==== 5-Dec-2017::18:13:24 ===
node           : rabbit@MacOSX
home dir       : /Users/mengday
config file(s) : /usr/local/etc/rabbitmq/rabbitmq.config
cookie hash    : 00v11sjZSBSIWTJU/BkuFg==
log            : /usr/local/var/log/rabbitmq/rabbit@MacOSX.log
sasl log       : /usr/local/var/log/rabbitmq/rabbit@MacOSX-sasl.log
database dir   : /usr/local/var/lib/rabbitmq/mnesia/rabbit@MacOSX
[email protected]:
  * connected to epmd (port 4369) on localhost
  * epmd reports node 'rabbit' running on port 25672
  * TCP connection succeeded but Erlang distribution failed

  * Hostname mismatch: node "[email protected]" believes its host is different. Please ensure that hostnames resolve the same way locally and on "[email protected]"

其他網上找到的答案有人說重啟一下就好了,可以試一下,並不好使

// 方式一
rabbitmq-server stop
rabbitmq-server start
// 方式二
ps ax | grep rabbit
kill -9 PID
  • {error,”Cookie file /Users/mengday/.erlang.cookie must be accessible by owner only”}

該錯是由於.erlang.cookie許可權的原因造成的,需要修改許可權chmod 400 .erlang.cookie

我的微信公眾號:

相關推薦

RabbitMQ入門教程()RabbitMQ單機叢集搭建

叢集簡介 理解叢集先理解一下元資料 佇列元資料:佇列的名稱和宣告佇列時設定的屬性(是否持久化、是否自動刪除、佇列所屬的節點) 交換機元資料:交換機的名稱、型別、屬性(是否持久化等) 繫結元資料:一張簡單的表格展示瞭如何將訊息路由到佇列。包含的列有 交換機名

RabbitMQ入門教程(五)普通叢集和映象叢集

普通叢集 推薦一篇優秀的文章: 映象叢集 映象叢集的特點:所有節點的訊息都會進行同步。RabbitMQ是沒有中心的。 Rabbit映象功能,需要基於rabbitmq策略來實現,政策是用來控制和修改群集範圍的某個vhost佇列行為和Exchan

RabbitMQ入門教程(一)訊息屬性Properties

簡介 傳送訊息可以為訊息指定一些引數 Delivery mode: 是否持久化,1 - Non-persistent,2 - Persistent Headers:Headers can have

ExtJs 入門教程[資料代理 DataProxy]

一、語法1、MemoryProxy(獲取本地資料) var myData =[[data1],[data2]] var store = new Ext.data.Store({ proxy: new Ext.data.MemoryProxy(myData),

webpack4 系列教程()Clean Plugin and Watch Mode

作者按:因為教程所示圖片使用的是 github 倉庫圖片,網速過慢的朋友請移步《webpack4 系列教程(十四):Clean Plugin and Watch Mode》原文地址。更歡迎來我的小站看更多原創內容:godbmw.com,進行“姿勢”交流 ♪(∇*) 0.

MongoDB最簡單的入門教程使用Spring Boot操作MongoDB

Spring Boot 是一個輕量級框架,可以完成基於 Spring 的應用程式的大部分配置工作。Spring Boot的目的是提供一組工具,以便快速構建容易配置的Spring應用程式,省去大量傳統Spring專案的繁瑣配置。 MongoDB是一個基於分散式檔

【QT】QT從零入門教程(一)QT自定義視窗

  首先是借鑑了網上的部落格,實現無邊框,自由拖動的自定義視窗效果。 #ifndef CUSTOMWINDOW_H #define CUSTOMWINDOW_H #include <QtGui> #include <QtWidg

Spring Boot教程基於自定義註解的AOP資料來源自動切換

上一篇文章講到了多資料來源的配置和手動切換,手動切換費時費力,下面我們改進一下,改成基於註解的AOP資料來源自動切換。 基礎知識不在贅述,直接上程式碼: public class DataSourceContextHolder { private static

WebGL簡易教程()陰影

目錄 1. 概述 2. 示例 2.1. 著色器部分 2.1.1. 幀快取著色器 2.1.2. 顏色快取著色器 2.2. 繪製部分 2.2.1.

RabbitMQ使用教程釋出/訂閱模式—Publish/Subscribe

一、釋出/訂閱模式說明 今天我們來學習一點新的東西,之前我們是將一個訊息傳送給了一個特定的消費者,今天的做法完全不同,不再發送給某一個消費者,而是將一個訊息傳送給多個消費者,這便是:釋出/訂閱模式。 我們將使用該模式來實現一個日誌系統:一個程式產生日誌,一個

RabbitMQ入門教程(一)安裝和常用命令

一:Mac安裝 Mac安裝比Windows安裝更加方便,也不需要再額外配置Web外掛,因為在安裝的時候預設已經配置好了 // 在Updating Homebrew...時可能會卡一會,只需要等就行了 // 在安裝的過程中可能因為網路問題,可能會有部分會失

RabbitMQ入門教程(七)主題交換機Topics

簡介 本節主要演示交換機的另一種型別:主題型別topic,直連線型別direct必須是生產者釋出訊息指定的routingKey和消費者在佇列繫結時指定的routingKey完全相等時才能匹配到佇列上,與direct不同,topic可以進行模糊匹配,可以使用星號

RabbitMQ入門教程(二)簡介和基本概念

一:簡介 RabbitMQ是一個開源的AMQP實現,伺服器端用Erlang語言編寫,支援多種客戶端。用於在分散式系統中儲存轉發訊息,在易用性、擴充套件性、高可用性等方面表現不俗,訊息佇列是一種應用系統之間的通訊方法,是通過讀寫出入佇列的訊息來通訊(RPC則是通

RabbitMQ入門教程(十三)虛擬主機vhost與許可權管理

虛擬主機vhost 每一個RabbitMQ伺服器都能建立虛擬訊息伺服器,我們稱之為虛擬主機。每一個vhost本質上是一個mini版的RabbitMQ伺服器,擁有自己的交換機、佇列、繫結等,擁有自己的許可權機制。vhost之於Rabbit就像虛擬機器之於物理機一

RabbitMQ入門教程(六)路由選擇Routing

簡介 本節主要演示使用直連線型別,將多個路由鍵繫結到同一個佇列上。也可以將同一個鍵繫結到多個佇列上(多重繫結multiple bindings),此時滿足鍵的佇列都能收到訊息,不滿足的直接被丟棄。

RabbitMQ系列教程之三發布/訂閱(Publish/Subscribe)

mqc 標題 整合 參數 cti 事情 return 控制臺 run (本教程是使用Net客戶端,也就是針對微軟技術平臺的) 在前一個教程中,我們創建了一個工作隊列。工作隊列背後的假設是每個任務會被交付給一個【工人】。在這一部分我們將做一些完全不同的事情--我們將向多個

RabbitMQ入門教程

fanout color -i www 快速 單播 odi 區別 multi 1.引言 RabbitMQ——Rabbit Message Queue的簡寫,但不能僅僅理解其為消息隊列,消息代理更合適。RabbitMQ 是一個由 Erlang 語言開發的AMQP(高級消息隊列

Spring Boot(RabbitMQ延遲隊列

system ofo 註意 contex ride build isa config msg 一、前言 延遲隊列的使用場景:1.未按時支付的訂單,30分鐘過期之後取消訂單;2.給活躍度比較低的用戶間隔N天之後推送消息,提高活躍度;3.過1分鐘給新註冊會員的用戶,發送註冊郵件

Spring Boot(RabbitMQ延遲佇列

一、前言 延遲佇列的使用場景:1.未按時支付的訂單,30分鐘過期之後取消訂單;2.給活躍度比較低的使用者間隔N天之後推送訊息,提高活躍度;3.過1分鐘給新註冊會員的使用者,傳送註冊郵件等。 <!--more--> 實現延遲佇列的方式有兩種: 通過訊息過期後進入死信交換器,再由交換器轉

RabbitMQ訊息佇列-啟用SSL安全通訊

如果RabbitMQ服務在內網中,只有內網的應用連線,我們認為這些連線都是安全的,但是個別情況我們需要讓RabbitMQ對外提供服務。這種情況有兩種解決方案: 在RabbitMQ外層在封裝一層應用,應用對外提供服務,本質來說RabbitMQ還是隻對內網提供服務。相對更安全,但靈活