消息隊列之 RabbitMQ

關(guān)于消息隊列,從前年開始斷斷續(xù)續(xù)看了些資料行贪,想寫很久了漾稀,但一直沒騰出空,近來分別碰到幾個朋友聊這塊的技術(shù)選型建瘫,是時候把這塊的知識整理記錄一下了崭捍。

市面上的消息隊列產(chǎn)品有很多,比如老牌的 ActiveMQ啰脚、RabbitMQ 缕贡,目前我看最火的 Kafka ,還有 ZeroMQ ,去年底阿里巴巴捐贈給 Apache 的 RocketMQ 晾咪,連 redis 這樣的 NoSQL 數(shù)據(jù)庫也支持 MQ 功能收擦。總之這塊知名的產(chǎn)品就有十幾種谍倦,就我自己的使用經(jīng)驗和興趣只打算談?wù)?RabbitMQ塞赂、Kafka 和 ActiveMQ ,本文先講 RabbitMQ 昼蛀,在此之前先看下消息隊列的相關(guān)概念宴猾。

什么叫消息隊列

消息(Message)是指在應(yīng)用間傳送的數(shù)據(jù)。消息可以非常簡單叼旋,比如只包含文本字符串仇哆,也可以更復(fù)雜,可能包含嵌入對象夫植。

消息隊列(Message Queue)是一種應(yīng)用間的通信方式讹剔,消息發(fā)送后可以立即返回,由消息系統(tǒng)來確保消息的可靠傳遞详民。消息發(fā)布者只管把消息發(fā)布到 MQ 中而不用管誰來取延欠,消息使用者只管從 MQ 中取消息而不管是誰發(fā)布的。這樣發(fā)布者和使用者都不用知道對方的存在沈跨。

為何用消息隊列

從上面的描述中可以看出消息隊列是一種應(yīng)用間的異步協(xié)作機制由捎,那什么時候需要使用 MQ 呢?

以常見的訂單系統(tǒng)為例饿凛,用戶點擊【下單】按鈕之后的業(yè)務(wù)邏輯可能包括:扣減庫存狞玛、生成相應(yīng)單據(jù)、發(fā)紅包涧窒、發(fā)短信通知为居。在業(yè)務(wù)發(fā)展初期這些邏輯可能放在一起同步執(zhí)行,隨著業(yè)務(wù)的發(fā)展訂單量增長杀狡,需要提升系統(tǒng)服務(wù)的性能,這時可以將一些不需要立即生效的操作拆分出來異步執(zhí)行贰镣,比如發(fā)放紅包呜象、發(fā)短信通知等。這種場景下就可以用 MQ 碑隆,在下單的主流程(比如扣減庫存恭陡、生成相應(yīng)單據(jù))完成之后發(fā)送一條消息到 MQ 讓主流程快速完結(jié),而由另外的單獨線程拉取MQ的消息(或者由 MQ 推送消息)上煤,當發(fā)現(xiàn) MQ 中有發(fā)紅包或發(fā)短信之類的消息時休玩,執(zhí)行相應(yīng)的業(yè)務(wù)邏輯。

以上是用于業(yè)務(wù)解耦的情況,其它常見場景包括最終一致性拴疤、廣播永部、錯峰流控等等。

RabbitMQ 特點

RabbitMQ 是一個由 Erlang 語言開發(fā)的 AMQP 的開源實現(xiàn)呐矾。

AMQP :Advanced Message Queue苔埋,高級消息隊列協(xié)議。它是應(yīng)用層協(xié)議的一個開放標準蜒犯,為面向消息的中間件設(shè)計组橄,基于此協(xié)議的客戶端與消息中間件可傳遞消息,并不受產(chǎn)品罚随、開發(fā)語言等條件的限制玉工。

RabbitMQ 最初起源于金融系統(tǒng),用于在分布式系統(tǒng)中存儲轉(zhuǎn)發(fā)消息淘菩,在易用性遵班、擴展性、高可用性等方面表現(xiàn)不俗瞄勾。具體特點包括:

  1. 可靠性(Reliability)
    RabbitMQ 使用一些機制來保證可靠性费奸,如持久化、傳輸確認进陡、發(fā)布確認愿阐。

  2. 靈活的路由(Flexible Routing)
    在消息進入隊列之前,通過 Exchange 來路由消息的趾疚。對于典型的路由功能缨历,RabbitMQ 已經(jīng)提供了一些內(nèi)置的 Exchange 來實現(xiàn)。針對更復(fù)雜的路由功能糙麦,可以將多個 Exchange 綁定在一起辛孵,也通過插件機制實現(xiàn)自己的 Exchange 。

  3. 消息集群(Clustering)
    多個 RabbitMQ 服務(wù)器可以組成一個集群赡磅,形成一個邏輯 Broker 魄缚。

  4. 高可用(Highly Available Queues)
    隊列可以在集群中的機器上進行鏡像,使得在部分節(jié)點出問題的情況下隊列仍然可用焚廊。

  5. 多種協(xié)議(Multi-protocol)
    RabbitMQ 支持多種消息隊列協(xié)議冶匹,比如 STOMP、MQTT 等等咆瘟。

  6. 多語言客戶端(Many Clients)
    RabbitMQ 幾乎支持所有常用語言嚼隘,比如 Java、.NET袒餐、Ruby 等等飞蛹。

  7. 管理界面(Management UI)
    RabbitMQ 提供了一個易用的用戶界面谤狡,使得用戶可以監(jiān)控和管理消息 Broker 的許多方面。

  8. 跟蹤機制(Tracing)
    如果消息異常卧檐,RabbitMQ 提供了消息跟蹤機制墓懂,使用者可以找出發(fā)生了什么。

  9. 插件機制(Plugin System)
    RabbitMQ 提供了許多插件泄隔,來從多方面進行擴展拒贱,也可以編寫自己的插件。

RabbitMQ 中的概念模型

消息模型

所有 MQ 產(chǎn)品從模型抽象上來說都是一樣的過程:
消費者(consumer)訂閱某個隊列佛嬉。生產(chǎn)者(producer)創(chuàng)建消息逻澳,然后發(fā)布到隊列(queue)中,最后將消息發(fā)送到監(jiān)聽的消費者暖呕。

image.png
RabbitMQ 基本概念

上面只是最簡單抽象的描述斜做,具體到 RabbitMQ 則有更詳細的概念需要解釋。上面介紹過 RabbitMQ 是 AMQP 協(xié)議的一個開源實現(xiàn)湾揽,所以其內(nèi)部實際上也是 AMQP 中的基本概念:

image.png
  1. Message
    消息瓤逼,消息是不具名的,它由消息頭和消息體組成库物。消息體是不透明的霸旗,而消息頭則由一系列的可選屬性組成,這些屬性包括routing-key(路由鍵)戚揭、priority(相對于其他消息的優(yōu)先權(quán))诱告、delivery-mode(指出該消息可能需要持久性存儲)等。
  2. Publisher
    消息的生產(chǎn)者民晒,也是一個向交換器發(fā)布消息的客戶端應(yīng)用程序精居。
  3. Exchange
    交換器,用來接收生產(chǎn)者發(fā)送的消息并將這些消息路由給服務(wù)器中的隊列潜必。
  4. Binding
    綁定靴姿,用于消息隊列和交換器之間的關(guān)聯(lián)。一個綁定就是基于路由鍵將交換器和消息隊列連接起來的路由規(guī)則磁滚,所以可以將交換器理解成一個由綁定構(gòu)成的路由表佛吓。
  5. Queue
    消息隊列,用來保存消息直到發(fā)送給消費者垂攘。它是消息的容器维雇,也是消息的終點。一個消息可投入一個或多個隊列搜贤。消息一直在隊列里面,等待消費者連接到這個隊列將其取走钝凶。
  6. Connection
    網(wǎng)絡(luò)連接仪芒,比如一個TCP連接唁影。
  7. Channel
    信道,多路復(fù)用連接中的一條獨立的雙向數(shù)據(jù)流通道掂名。信道是建立在真實的TCP連接內(nèi)地虛擬連接据沈,AMQP 命令都是通過信道發(fā)出去的,不管是發(fā)布消息饺蔑、訂閱隊列還是接收消息锌介,這些動作都是通過信道完成。因為對于操作系統(tǒng)來說建立和銷毀 TCP 都是非常昂貴的開銷猾警,所以引入了信道的概念孔祸,以復(fù)用一條 TCP 連接。
  8. Consumer
    消息的消費者发皿,表示一個從消息隊列中取得消息的客戶端應(yīng)用程序崔慧。
  9. Virtual Host
    虛擬主機,表示一批交換器穴墅、消息隊列和相關(guān)對象惶室。虛擬主機是共享相同的身份認證和加密環(huán)境的獨立服務(wù)器域。每個 vhost 本質(zhì)上就是一個 mini 版的 RabbitMQ 服務(wù)器玄货,擁有自己的隊列皇钞、交換器、綁定和權(quán)限機制松捉。vhost 是 AMQP 概念的基礎(chǔ)夹界,必須在連接時指定,RabbitMQ 默認的 vhost 是 / 惩坑。
  10. Broker
    表示消息隊列服務(wù)器實體掉盅。
AMQP 中的消息路由

AMQP 中消息的路由過程和 Java 開發(fā)者熟悉的 JMS 存在一些差別,AMQP 中增加了 Exchange 和 Binding 的角色以舒。生產(chǎn)者把消息發(fā)布到 Exchange 上趾痘,消息最終到達隊列并被消費者接收,而 Binding 決定交換器的消息應(yīng)該發(fā)送到那個隊列蔓钟。

image.png
Exchange 類型

Exchange分發(fā)消息時根據(jù)類型的不同分發(fā)策略有區(qū)別永票,目前共四種類型:direct、fanout滥沫、topic侣集、headers 。headers 匹配 AMQP 消息的 header 而不是路由鍵兰绣,此外 headers 交換器和 direct 交換器完全一致世分,但性能差很多,目前幾乎用不到了缀辩,所以直接看另外三種類型:

  1. direct
image.png
消息中的路由鍵(routing key)如果和 Binding 中的 binding key 一致臭埋, 交換器就將消息發(fā)到對應(yīng)的隊列中踪央。路由鍵與隊列名完全匹配,如果一個隊列綁定到交換機要求路由鍵為“dog”瓢阴,則只轉(zhuǎn)發(fā) routing key 標記為“dog”的消息畅蹂,不會轉(zhuǎn)發(fā)“dog.puppy”,也不會轉(zhuǎn)發(fā)“dog.guard”等等荣恐。它是完全匹配液斜、單播的模式。
  1. fanout

    image.png
每個發(fā)到 fanout 類型交換器的消息都會分到所有綁定的隊列上去叠穆。fanout 交換器不處理路由鍵少漆,只是簡單的將隊列綁定到交換器上,每個發(fā)送到交換器的消息都會被轉(zhuǎn)發(fā)到與該交換器綁定的所有隊列上痹束。很像子網(wǎng)廣播检疫,每臺子網(wǎng)內(nèi)的主機都獲得了一份復(fù)制的消息。fanout 類型轉(zhuǎn)發(fā)消息是最快的祷嘶。
  1. topic
image.png
topic 交換器通過模式匹配分配消息的路由鍵屬性屎媳,將路由鍵和某個模式進行匹配,此時隊列需要綁定到一個模式上论巍。它將路由鍵和綁定鍵的字符串切分成單詞烛谊,這些單詞之間用點隔開。它同樣也會識別兩個通配符:符號“#”和符號“*”嘉汰。#匹配0個或多個單詞丹禀,*匹配不多不少一個單詞。

RabbitMQ 安裝

一般來說安裝 RabbitMQ 之前要安裝 Erlang 鞋怀,可以去Erlang官網(wǎng)下載双泪。接著去RabbitMQ官網(wǎng)下載安裝包,之后解壓縮即可密似。根據(jù)操作系統(tǒng)不同官網(wǎng)提供了相應(yīng)的安裝說明:Windows焙矛、Debian / UbuntuRPM-based Linux残腌、Mac

如果是Mac 用戶村斟,個人推薦使用 HomeBrew 來安裝,安裝前要先更新 brew:

brew update

接著安裝 rabbitmq 服務(wù)器:

brew install rabbitmq

這樣 RabbitMQ 就安裝好了抛猫,安裝過程中會自動其所依賴的 Erlang 蟆盹。

RabbitMQ 運行和管理

  1. 啟動
    啟動很簡單,找到安裝后的 RabbitMQ 所在目錄下的 sbin 目錄闺金,可以看到該目錄下有6個以 rabbitmq 開頭的可執(zhí)行文件逾滥,直接執(zhí)行 rabbitmq-server 即可,下面將 RabbitMQ 的安裝位置以 . 代替败匹,啟動命令就是:
./sbin/rabbitmq-server

啟動正常的話會看到一些啟動過程信息和最后的 completed with 7 plugins寨昙,這也說明啟動的時候默認加載了7個插件面哥。

image.png
  1. 后臺啟動
    如果想讓 RabbitMQ 以守護程序的方式在后臺運行,可以在啟動的時候加上 -detached 參數(shù):
./sbin/rabbitmq-server -detached

  1. 查詢服務(wù)器狀態(tài)
    sbin 目錄下有個特別重要的文件叫 rabbitmqctl 毅待,它提供了 RabbitMQ 管理需要的幾乎一站式解決方案,絕大部分的運維命令它都可以提供归榕。
    查詢 RabbitMQ 服務(wù)器的狀態(tài)信息可以用參數(shù) status :
./sbin/rabbitmqctl status

該命令將輸出服務(wù)器的很多信息尸红,比如 RabbitMQ 和 Erlang 的版本、OS 名稱刹泄、內(nèi)存等等

  1. 關(guān)閉 RabbitMQ 節(jié)點
    我們知道 RabbitMQ 是用 Erlang 語言寫的外里,在Erlang 中有兩個概念:節(jié)點和應(yīng)用程序。節(jié)點就是 Erlang 虛擬機的每個實例特石,而多個 Erlang 應(yīng)用程序可以運行在同一個節(jié)點之上盅蝗。節(jié)點之間可以進行本地通信(不管他們是不是運行在同一臺服務(wù)器之上)。比如一個運行在節(jié)點A上的應(yīng)用程序可以調(diào)用節(jié)點B上應(yīng)用程序的方法姆蘸,就好像調(diào)用本地函數(shù)一樣墩莫。如果應(yīng)用程序由于某些原因奔潰,Erlang 節(jié)點會自動嘗試重啟應(yīng)用程序逞敷。
    如果要關(guān)閉整個 RabbitMQ 節(jié)點可以用參數(shù) stop :
./sbin/rabbitmqctl stop

它會和本地節(jié)點通信并指示其干凈的關(guān)閉狂秦,也可以指定關(guān)閉不同的節(jié)點,包括遠程節(jié)點推捐,只需要傳入?yún)?shù) -n :

./sbin/rabbitmqctl -n rabbit@server.example.com stop 

-n node 默認 node 名稱是 rabbit@server 裂问,如果你的主機名是 server.example.com ,那么 node 名稱就是 rabbit@server.example.com 牛柒。

  1. 關(guān)閉 RabbitMQ 應(yīng)用程序
    如果只想關(guān)閉應(yīng)用程序堪簿,同時保持 Erlang 節(jié)點運行則可以用 stop_app:
./sbin/rabbitmqctl stop_app

這個命令在后面要講的集群模式中將會很有用。

  1. 啟動 RabbitMQ 應(yīng)用程序
./sbin/rabbitmqctl start_app

  1. 重置 RabbitMQ 節(jié)點
./sbin/rabbitmqctl reset

該命令將清除所有的隊列皮壁。

  1. 查看已聲明的隊列
./sbin/rabbitmqctl list_queues

  1. 查看交換器
./sbin/rabbitmqctl list_exchanges

該命令還可以附加參數(shù)椭更,比如列出交換器的名稱、類型闪彼、是否持久化甜孤、是否自動刪除:

./sbin/rabbitmqctl list_exchanges name type durable auto_delete

  1. 查看綁定
./sbin/rabbitmqctl list_bindings

Java 客戶端訪問

RabbitMQ 支持多種語言訪問,以 Java 為例看下一般使用 RabbitMQ 的步驟畏腕。

  1. maven工程的pom文件中添加依賴
<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>4.1.0</version>
</dependency>

  1. 消息生產(chǎn)者
package org.study.rabbitmq;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Producer {

    public static void main(String[] args) throws IOException, TimeoutException {
        //創(chuàng)建連接工廠
        ConnectionFactory factory = new ConnectionFactory();
        factory.setUsername("guest");
        factory.setPassword("guest");
        //設(shè)置 RabbitMQ 地址
        factory.setHost("localhost");
        //建立到代理服務(wù)器到連接
        Connection conn = factory.newConnection();
        //獲得信道
        Channel channel = conn.createChannel();
        //聲明交換器
        String exchangeName = "hello-exchange";
        channel.exchangeDeclare(exchangeName, "direct", true);

        String routingKey = "hola";
        //發(fā)布消息
        byte[] messageBodyBytes = "quit".getBytes();
        channel.basicPublish(exchangeName, routingKey, null, messageBodyBytes);

        channel.close();
        conn.close();
    }
}

  1. 消息消費者
package org.study.rabbitmq;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setHost("localhost");
        //建立到代理服務(wù)器到連接
        Connection conn = factory.newConnection();
        //獲得信道
        final Channel channel = conn.createChannel();
        //聲明交換器
        String exchangeName = "hello-exchange";
        channel.exchangeDeclare(exchangeName, "direct", true);
        //聲明隊列
        String queueName = channel.queueDeclare().getQueue();
        String routingKey = "hola";
        //綁定隊列缴川,通過鍵 hola 將隊列和交換器綁定起來
        channel.queueBind(queueName, exchangeName, routingKey);

        while(true) {
            //消費消息
            boolean autoAck = false;
            String consumerTag = "";
            channel.basicConsume(queueName, autoAck, consumerTag, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag,
                                           Envelope envelope,
                                           AMQP.BasicProperties properties,
                                           byte[] body) throws IOException {
                    String routingKey = envelope.getRoutingKey();
                    String contentType = properties.getContentType();
                    System.out.println("消費的路由鍵:" + routingKey);
                    System.out.println("消費的內(nèi)容類型:" + contentType);
                    long deliveryTag = envelope.getDeliveryTag();
                    //確認消息
                    channel.basicAck(deliveryTag, false);
                    System.out.println("消費的消息體內(nèi)容:");
                    String bodyStr = new String(body, "UTF-8");
                    System.out.println(bodyStr);

                }
            });
        }
    }
}

  1. 啟動 RabbitMQ 服務(wù)器
./sbin/rabbitmq-server

  1. 運行 Consumer
    先運行 Consumer ,這樣當生產(chǎn)者發(fā)送消息的時候能在消費者后端看到消息記錄描馅。
  2. 運行 Producer
    接著運行 Producer ,發(fā)布一條消息把夸,在 Consumer 的控制臺能看到接收的消息:
image.png

RabbitMQ 集群

RabbitMQ 最優(yōu)秀的功能之一就是內(nèi)建集群,這個功能設(shè)計的目的是允許消費者和生產(chǎn)者在節(jié)點崩潰的情況下繼續(xù)運行铭污,以及通過添加更多的節(jié)點來線性擴展消息通信吞吐量恋日。RabbitMQ 內(nèi)部利用 Erlang 提供的分布式通信框架 OTP 來滿足上述需求膀篮,使客戶端在失去一個 RabbitMQ 節(jié)點連接的情況下,還是能夠重新連接到集群中的任何其他節(jié)點繼續(xù)生產(chǎn)岂膳、消費消息誓竿。

RabbitMQ 集群中的一些概念

RabbitMQ 會始終記錄以下四種類型的內(nèi)部元數(shù)據(jù):

  1. 隊列元數(shù)據(jù)
    包括隊列名稱和它們的屬性,比如是否可持久化谈截,是否自動刪除
  2. 交換器元數(shù)據(jù)
    交換器名稱筷屡、類型、屬性
  3. 綁定元數(shù)據(jù)
    內(nèi)部是一張表格記錄如何將消息路由到隊列
  4. vhost 元數(shù)據(jù)
    為 vhost 內(nèi)部的隊列簸喂、交換器毙死、綁定提供命名空間和安全屬性

在單一節(jié)點中,RabbitMQ 會將所有這些信息存儲在內(nèi)存中喻鳄,同時將標記為可持久化的隊列扼倘、交換器、綁定存儲到硬盤上除呵。存到硬盤上可以確保隊列和交換器在節(jié)點重啟后能夠重建再菊。而在集群模式下同樣也提供兩種選擇:存到硬盤上(獨立節(jié)點的默認設(shè)置),存在內(nèi)存中颜曾。

如果在集群中創(chuàng)建隊列袄简,集群只會在單個節(jié)點而不是所有節(jié)點上創(chuàng)建完整的隊列信息(元數(shù)據(jù)、狀態(tài)泛啸、內(nèi)容)绿语。結(jié)果是只有隊列的所有者節(jié)點知道有關(guān)隊列的所有信息,因此當集群節(jié)點崩潰時候址,該節(jié)點的隊列和綁定就消失了吕粹,并且任何匹配該隊列的綁定的新消息也丟失了。還好RabbitMQ 2.6.0之后提供了鏡像隊列以避免集群節(jié)點故障導致的隊列內(nèi)容不可用岗仑。

RabbitMQ 集群中可以共享 user匹耕、vhost、exchange等荠雕,所有的數(shù)據(jù)和狀態(tài)都是必須在所有節(jié)點上復(fù)制的稳其,例外就是上面所說的消息隊列。RabbitMQ 節(jié)點可以動態(tài)的加入到集群中炸卑。

當在集群中聲明隊列既鞠、交換器、綁定的時候盖文,這些操作會直到所有集群節(jié)點都成功提交元數(shù)據(jù)變更后才返回嘱蛋。集群中有內(nèi)存節(jié)點和磁盤節(jié)點兩種類型,內(nèi)存節(jié)點雖然不寫入磁盤,但是它的執(zhí)行比磁盤節(jié)點要好洒敏。內(nèi)存節(jié)點可以提供出色的性能龄恋,磁盤節(jié)點能保障配置信息在節(jié)點重啟后仍然可用,那集群中如何平衡這兩者呢凶伙?

RabbitMQ 只要求集群中至少有一個磁盤節(jié)點郭毕,所有其他節(jié)點可以是內(nèi)存節(jié)點,當節(jié)點加入火離開集群時函荣,它們必須要將該變更通知到至少一個磁盤節(jié)點铣卡。如果只有一個磁盤節(jié)點,剛好又是該節(jié)點崩潰了偏竟,那么集群可以繼續(xù)路由消息,但不能創(chuàng)建隊列敞峭、創(chuàng)建交換器踊谋、創(chuàng)建綁定、添加用戶旋讹、更改權(quán)限殖蚕、添加或刪除集群節(jié)點。換句話說集群中的唯一磁盤節(jié)點崩潰的話沉迹,集群仍然可以運行睦疫,但知道該節(jié)點恢復(fù),否則無法更改任何東西鞭呕。

RabbitMQ 集群配置和啟動

如果是在一臺機器上同時啟動多個 RabbitMQ 節(jié)點來組建集群的話蛤育,只用上面介紹的方式啟動第二、第三個節(jié)點將會因為節(jié)點名稱和端口沖突導致啟動失敗葫松。所以在每次調(diào)用 rabbitmq-server 命令前瓦糕,設(shè)置環(huán)境變量 RABBITMQ_NODENAME 和 RABBITMQ_NODE_PORT 來明確指定唯一的節(jié)點名稱和端口。下面的例子端口號從5672開始腋么,每個新啟動的節(jié)點都加1咕娄,節(jié)點也分別命名為test_rabbit_1、test_rabbit_2珊擂、test_rabbit_3圣勒。

啟動第1個節(jié)點:

RABBITMQ_NODENAME=test_rabbit_1 RABBITMQ_NODE_PORT=5672 ./sbin/rabbitmq-server -detached

啟動第2個節(jié)點:

RABBITMQ_NODENAME=test_rabbit_2 RABBITMQ_NODE_PORT=5673 ./sbin/rabbitmq-server -detached

啟動第2個節(jié)點前建議將 RabbitMQ 默認激活的插件關(guān)掉,否則會存在使用了某個插件的端口號沖突摧扇,導致節(jié)點啟動不成功圣贸。

現(xiàn)在第2個節(jié)點和第1個節(jié)點都是獨立節(jié)點,它們并不知道其他節(jié)點的存在扛稽。集群中除第一個節(jié)點外后加入的節(jié)點需要獲取集群中的元數(shù)據(jù)旁趟,所以要先停止 Erlang 節(jié)點上運行的 RabbitMQ 應(yīng)用程序,并重置該節(jié)點元數(shù)據(jù),再加入并且獲取集群的元數(shù)據(jù)锡搜,最后重新啟動 RabbitMQ 應(yīng)用程序橙困。

停止第2個節(jié)點的應(yīng)用程序:

./sbin/rabbitmqctl -n test_rabbit_2 stop_app

重置第2個節(jié)點元數(shù)據(jù):

./sbin/rabbitmqctl -n test_rabbit_2 reset

第2節(jié)點加入第1個節(jié)點組成的集群:

./sbin/rabbitmqctl -n test_rabbit_2 join_cluster test_rabbit_1@localhost

啟動第2個節(jié)點的應(yīng)用程序

./sbin/rabbitmqctl -n test_rabbit_2 start_app

第3個節(jié)點的配置過程和第2個節(jié)點類似:

RABBITMQ_NODENAME=test_rabbit_3 RABBITMQ_NODE_PORT=5674 ./sbin/rabbitmq-server -detached

./sbin/rabbitmqctl -n test_rabbit_3 stop_app

./sbin/rabbitmqctl -n test_rabbit_3 reset

./sbin/rabbitmqctl -n test_rabbit_3 join_cluster test_rabbit_1@localhost

./sbin/rabbitmqctl -n test_rabbit_3 start_app

RabbitMQ 集群運維

停止某個指定的節(jié)點,比如停止第2個節(jié)點:

RABBITMQ_NODENAME=test_rabbit_2 ./sbin/rabbitmqctl stop

查看節(jié)點3的集群狀態(tài):

./sbin/rabbitmqctl -n test_rabbit_3 cluster_status

參考:http://www.reibang.com/p/79ca08116d57

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末耕餐,一起剝皮案震驚了整個濱河市凡傅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肠缔,老刑警劉巖夏跷,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異明未,居然都是意外死亡槽华,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門趟妥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來猫态,“玉大人,你說我怎么就攤上這事披摄∏籽” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵疚膊,是天一觀的道長义辕。 經(jīng)常有香客問我,道長寓盗,這世上最難降的妖魔是什么灌砖? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮傀蚌,結(jié)果婚禮上周崭,老公的妹妹穿的比我還像新娘。我一直安慰自己喳张,他們只是感情好续镇,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著销部,像睡著了一般摸航。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上舅桩,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天酱虎,我揣著相機與錄音,去河邊找鬼擂涛。 笑死读串,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播恢暖,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼排监,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了杰捂?” 一聲冷哼從身側(cè)響起舆床,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嫁佳,沒想到半個月后挨队,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡蒿往,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年盛垦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓤漏。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡腾夯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赌蔑,到底是詐尸還是另有隱情,我是刑警寧澤竟秫,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布娃惯,位于F島的核電站絮识,受9級特大地震影響槽畔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜涕蜂,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一馒稍、第九天 我趴在偏房一處隱蔽的房頂上張望皿哨。 院中可真熱鬧,春花似錦纽谒、人聲如沸证膨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽央勒。三九已至,卻和暖如春澳化,著一層夾襖步出監(jiān)牢的瞬間崔步,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工缎谷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留井濒,地道東北人。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像瑞你,于是被迫代替她去往敵國和親酪惭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 關(guān)于消息隊列捏悬,從前年開始斷斷續(xù)續(xù)看了些資料撞蚕,想寫很久了,但一直沒騰出空过牙,近來分別碰到幾個朋友聊這塊的技術(shù)選型甥厦,是時...
    預(yù)流閱讀 584,750評論 51 786
  • 關(guān)于消息隊列,從前年開始斷斷續(xù)續(xù)看了些資料寇钉,想寫很久了刀疙,但一直沒騰出空,近來分別碰到幾個朋友聊這塊的技術(shù)選型扫倡,是時...
    中v中閱讀 1,971評論 0 20
  • 什么叫消息隊列谦秧? 消息(Message)是指在應(yīng)用間傳送的數(shù)據(jù)。消息可以非常簡單撵溃,比如只包含文本字符串疚鲤,也可以更復(fù)...
    Agile_dev閱讀 2,373評論 0 24
  • 簡介: MQ全稱為Message Queue, 消息隊列(MQ)是一種應(yīng)用程序?qū)?yīng)用程序的通信方法。應(yīng)用程序通過讀...
    黑客和白帽子的故事閱讀 833評論 0 0
  • 我想投訴你缘挑,投訴你主動行賄 誰讓你予我一笑集歇,從此墮入腐敗 我想投訴你,投訴你有借無還 誰讓你借走了我的時光语淘,堆積沉...
    王小圈閱讀 249評論 2 4