關(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)不俗瞄勾。具體特點包括:
可靠性(Reliability)
RabbitMQ 使用一些機制來保證可靠性费奸,如持久化、傳輸確認进陡、發(fā)布確認愿阐。靈活的路由(Flexible Routing)
在消息進入隊列之前,通過 Exchange 來路由消息的趾疚。對于典型的路由功能缨历,RabbitMQ 已經(jīng)提供了一些內(nèi)置的 Exchange 來實現(xiàn)。針對更復(fù)雜的路由功能糙麦,可以將多個 Exchange 綁定在一起辛孵,也通過插件機制實現(xiàn)自己的 Exchange 。消息集群(Clustering)
多個 RabbitMQ 服務(wù)器可以組成一個集群赡磅,形成一個邏輯 Broker 魄缚。高可用(Highly Available Queues)
隊列可以在集群中的機器上進行鏡像,使得在部分節(jié)點出問題的情況下隊列仍然可用焚廊。多種協(xié)議(Multi-protocol)
RabbitMQ 支持多種消息隊列協(xié)議冶匹,比如 STOMP、MQTT 等等咆瘟。多語言客戶端(Many Clients)
RabbitMQ 幾乎支持所有常用語言嚼隘,比如 Java、.NET袒餐、Ruby 等等飞蛹。管理界面(Management UI)
RabbitMQ 提供了一個易用的用戶界面谤狡,使得用戶可以監(jiān)控和管理消息 Broker 的許多方面。跟蹤機制(Tracing)
如果消息異常卧檐,RabbitMQ 提供了消息跟蹤機制墓懂,使用者可以找出發(fā)生了什么。插件機制(Plugin System)
RabbitMQ 提供了許多插件泄隔,來從多方面進行擴展拒贱,也可以編寫自己的插件。
RabbitMQ 中的概念模型
消息模型
所有 MQ 產(chǎn)品從模型抽象上來說都是一樣的過程:
消費者(consumer)訂閱某個隊列佛嬉。生產(chǎn)者(producer)創(chuàng)建消息逻澳,然后發(fā)布到隊列(queue)中,最后將消息發(fā)送到監(jiān)聽的消費者暖呕。
RabbitMQ 基本概念
上面只是最簡單抽象的描述斜做,具體到 RabbitMQ 則有更詳細的概念需要解釋。上面介紹過 RabbitMQ 是 AMQP 協(xié)議的一個開源實現(xiàn)湾揽,所以其內(nèi)部實際上也是 AMQP 中的基本概念:
- Message
消息瓤逼,消息是不具名的,它由消息頭和消息體組成库物。消息體是不透明的霸旗,而消息頭則由一系列的可選屬性組成,這些屬性包括routing-key(路由鍵)戚揭、priority(相對于其他消息的優(yōu)先權(quán))诱告、delivery-mode(指出該消息可能需要持久性存儲)等。 - Publisher
消息的生產(chǎn)者民晒,也是一個向交換器發(fā)布消息的客戶端應(yīng)用程序精居。 - Exchange
交換器,用來接收生產(chǎn)者發(fā)送的消息并將這些消息路由給服務(wù)器中的隊列潜必。 - Binding
綁定靴姿,用于消息隊列和交換器之間的關(guān)聯(lián)。一個綁定就是基于路由鍵將交換器和消息隊列連接起來的路由規(guī)則磁滚,所以可以將交換器理解成一個由綁定構(gòu)成的路由表佛吓。 - Queue
消息隊列,用來保存消息直到發(fā)送給消費者垂攘。它是消息的容器维雇,也是消息的終點。一個消息可投入一個或多個隊列搜贤。消息一直在隊列里面,等待消費者連接到這個隊列將其取走钝凶。 - Connection
網(wǎng)絡(luò)連接仪芒,比如一個TCP連接唁影。 - Channel
信道,多路復(fù)用連接中的一條獨立的雙向數(shù)據(jù)流通道掂名。信道是建立在真實的TCP連接內(nèi)地虛擬連接据沈,AMQP 命令都是通過信道發(fā)出去的,不管是發(fā)布消息饺蔑、訂閱隊列還是接收消息锌介,這些動作都是通過信道完成。因為對于操作系統(tǒng)來說建立和銷毀 TCP 都是非常昂貴的開銷猾警,所以引入了信道的概念孔祸,以復(fù)用一條 TCP 連接。 - Consumer
消息的消費者发皿,表示一個從消息隊列中取得消息的客戶端應(yīng)用程序崔慧。 - Virtual Host
虛擬主機,表示一批交換器穴墅、消息隊列和相關(guān)對象惶室。虛擬主機是共享相同的身份認證和加密環(huán)境的獨立服務(wù)器域。每個 vhost 本質(zhì)上就是一個 mini 版的 RabbitMQ 服務(wù)器玄货,擁有自己的隊列皇钞、交換器、綁定和權(quán)限機制松捉。vhost 是 AMQP 概念的基礎(chǔ)夹界,必須在連接時指定,RabbitMQ 默認的 vhost 是 / 惩坑。 - Broker
表示消息隊列服務(wù)器實體掉盅。
AMQP 中的消息路由
AMQP 中消息的路由過程和 Java 開發(fā)者熟悉的 JMS 存在一些差別,AMQP 中增加了 Exchange 和 Binding 的角色以舒。生產(chǎn)者把消息發(fā)布到 Exchange 上趾痘,消息最終到達隊列并被消費者接收,而 Binding 決定交換器的消息應(yīng)該發(fā)送到那個隊列蔓钟。
Exchange 類型
Exchange分發(fā)消息時根據(jù)類型的不同分發(fā)策略有區(qū)別永票,目前共四種類型:direct、fanout滥沫、topic侣集、headers 。headers 匹配 AMQP 消息的 header 而不是路由鍵兰绣,此外 headers 交換器和 direct 交換器完全一致世分,但性能差很多,目前幾乎用不到了缀辩,所以直接看另外三種類型:
- direct
消息中的路由鍵(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”等等荣恐。它是完全匹配液斜、單播的模式。
-
fanout
image.png
每個發(fā)到 fanout 類型交換器的消息都會分到所有綁定的隊列上去叠穆。fanout 交換器不處理路由鍵少漆,只是簡單的將隊列綁定到交換器上,每個發(fā)送到交換器的消息都會被轉(zhuǎn)發(fā)到與該交換器綁定的所有隊列上痹束。很像子網(wǎng)廣播检疫,每臺子網(wǎng)內(nèi)的主機都獲得了一份復(fù)制的消息。fanout 類型轉(zhuǎn)發(fā)消息是最快的祷嘶。
- topic
topic 交換器通過模式匹配分配消息的路由鍵屬性屎媳,將路由鍵和某個模式進行匹配,此時隊列需要綁定到一個模式上论巍。它將路由鍵和綁定鍵的字符串切分成單詞烛谊,這些單詞之間用點隔開。它同樣也會識別兩個通配符:符號“#”和符號“*”嘉汰。#匹配0個或多個單詞丹禀,*匹配不多不少一個單詞。
RabbitMQ 安裝
一般來說安裝 RabbitMQ 之前要安裝 Erlang 鞋怀,可以去Erlang官網(wǎng)下載双泪。接著去RabbitMQ官網(wǎng)下載安裝包,之后解壓縮即可密似。根據(jù)操作系統(tǒng)不同官網(wǎng)提供了相應(yīng)的安裝說明:Windows焙矛、Debian / Ubuntu、RPM-based Linux残腌、Mac
如果是Mac 用戶村斟,個人推薦使用 HomeBrew 來安裝,安裝前要先更新 brew:
brew update
接著安裝 rabbitmq 服務(wù)器:
brew install rabbitmq
這樣 RabbitMQ 就安裝好了抛猫,安裝過程中會自動其所依賴的 Erlang 蟆盹。
RabbitMQ 運行和管理
- 啟動
啟動很簡單,找到安裝后的 RabbitMQ 所在目錄下的 sbin 目錄闺金,可以看到該目錄下有6個以 rabbitmq 開頭的可執(zhí)行文件逾滥,直接執(zhí)行 rabbitmq-server 即可,下面將 RabbitMQ 的安裝位置以 . 代替败匹,啟動命令就是:
./sbin/rabbitmq-server
啟動正常的話會看到一些啟動過程信息和最后的 completed with 7 plugins寨昙,這也說明啟動的時候默認加載了7個插件面哥。
- 后臺啟動
如果想讓 RabbitMQ 以守護程序的方式在后臺運行,可以在啟動的時候加上 -detached 參數(shù):
./sbin/rabbitmq-server -detached
- 查詢服務(wù)器狀態(tài)
sbin 目錄下有個特別重要的文件叫 rabbitmqctl 毅待,它提供了 RabbitMQ 管理需要的幾乎一站式解決方案,絕大部分的運維命令它都可以提供归榕。
查詢 RabbitMQ 服務(wù)器的狀態(tài)信息可以用參數(shù) status :
./sbin/rabbitmqctl status
該命令將輸出服務(wù)器的很多信息尸红,比如 RabbitMQ 和 Erlang 的版本、OS 名稱刹泄、內(nèi)存等等
- 關(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 牛柒。
- 關(guān)閉 RabbitMQ 應(yīng)用程序
如果只想關(guān)閉應(yīng)用程序堪簿,同時保持 Erlang 節(jié)點運行則可以用 stop_app:
./sbin/rabbitmqctl stop_app
這個命令在后面要講的集群模式中將會很有用。
- 啟動 RabbitMQ 應(yīng)用程序
./sbin/rabbitmqctl start_app
- 重置 RabbitMQ 節(jié)點
./sbin/rabbitmqctl reset
該命令將清除所有的隊列皮壁。
- 查看已聲明的隊列
./sbin/rabbitmqctl list_queues
- 查看交換器
./sbin/rabbitmqctl list_exchanges
該命令還可以附加參數(shù)椭更,比如列出交換器的名稱、類型闪彼、是否持久化甜孤、是否自動刪除:
./sbin/rabbitmqctl list_exchanges name type durable auto_delete
- 查看綁定
./sbin/rabbitmqctl list_bindings
Java 客戶端訪問
RabbitMQ 支持多種語言訪問,以 Java 為例看下一般使用 RabbitMQ 的步驟畏腕。
- maven工程的pom文件中添加依賴
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>4.1.0</version>
</dependency>
- 消息生產(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();
}
}
- 消息消費者
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);
}
});
}
}
}
- 啟動 RabbitMQ 服務(wù)器
./sbin/rabbitmq-server
- 運行 Consumer
先運行 Consumer ,這樣當生產(chǎn)者發(fā)送消息的時候能在消費者后端看到消息記錄描馅。 - 運行 Producer
接著運行 Producer ,發(fā)布一條消息把夸,在 Consumer 的控制臺能看到接收的消息:
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ù):
- 隊列元數(shù)據(jù)
包括隊列名稱和它們的屬性,比如是否可持久化谈截,是否自動刪除 - 交換器元數(shù)據(jù)
交換器名稱筷屡、類型、屬性 - 綁定元數(shù)據(jù)
內(nèi)部是一張表格記錄如何將消息路由到隊列 - 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