應(yīng)用架構(gòu)之【RabbitMQ+Keepalived】AMQP 消息隊列集群方案

RabbitMQ 是一個開源(遵循 MPL 協(xié)議)的消息代理和隊列服務(wù)器斯棒,用來通過普通協(xié)議在不同的應(yīng)用之間共享數(shù)據(jù)(跨平臺跨語言)涮母。RabbitMQ 是使用 Erlang 語言編寫辈挂,并且基于 AMQP 協(xié)議實現(xiàn)。

AMQP (Advanced Message Queuing Protocol)高級消息隊列協(xié)議绘盟。AMQP是應(yīng)用層協(xié)議的一個開放標(biāo)準(zhǔn)煤墙,為面向消息的中間件設(shè)計晌块,基于此協(xié)議的客戶端與消息中間件可傳遞消息瘤载,并不受產(chǎn)品碍脏、開發(fā)語言等條件的限制癣疟。AMQP 包括 Exchange 和 Binging 的角色,生產(chǎn)者(Producer)把消息發(fā)布到 Exchange 上潮酒,消息最終到達(dá)隊列并被消費者(Consumer)接收睛挚,而 Binding 決定交換器的消息應(yīng)該發(fā)送到哪個隊列。

Keepalived 是一款基于 VRRP 協(xié)議的輕量級服務(wù)高可用和負(fù)載均衡方案急黎,提供避免服務(wù)器單點故障和請求分流的能力扎狱。

本方案基于CentOS8系統(tǒng)設(shè)計侧到,建議在RedHat/CentOS系統(tǒng)中使用。部署數(shù)據(jù)庫集群使用服務(wù)器及網(wǎng)絡(luò)資源較多淤击,建議在實施前做好規(guī)劃工作匠抗,有利于部署工作順利、有序進(jìn)行污抬。

目錄

1.RabbitMQ 技術(shù)評估

2.RabbitMQ 單點安裝和配置

3.RabbitMQ 普通集群
-- 3.1 集群部署拓?fù)鋱D
-- 3.2 普通集群部署

4.RabbitMQ 鏡像集群
-- 4.1 集群部署拓?fù)鋱D
-- 4.2 鏡像集群部署

5.RabbitMQ 鏡像集群+ Keepalived 高可用
-- 5.1 集群部署拓?fù)鋱D
-- 5.2 高可用鏡像集群部署

6.RabbitMQ 運維管理
-- 6.1.通過可視化插件運維管理
-- 6.2.通過命令管道運維管理

7.Java 開發(fā)集成示例


1. RabbitMQ 技術(shù)評估

1汞贸、技術(shù)特點

  • 可靠性:使用了一些機(jī)制來保證可靠性,比如持久化印机、傳輸確認(rèn)矢腻、發(fā)布確認(rèn)。

  • 靈活的路由:在消息進(jìn)入隊列之前射赛,通過 Exchange 來路由消息多柑。對于典型的路由功能,RabbitMQ 已經(jīng)提供了一些內(nèi)置的 Exchange 來實現(xiàn)楣责。針對更復(fù)雜的路由功能竣灌,可以將多個 Exchange 綁定在一起,也通過插件機(jī)制實現(xiàn)自己的 Exchange秆麸。

  • 消息集群:多個 RabbitMQ 服務(wù)器可以組成一個集群初嘹,形成一個邏輯 Broker。

  • 高可用:隊列可以在集群中的機(jī)器上進(jìn)行鏡像沮趣,使得在部分節(jié)點出問題的情況下隊列仍然可用屯烦。

  • 多種協(xié)議:支持多種消息隊列協(xié)議,如 STOMP兔毒、MQTT 等。

  • 多種語言客戶端:幾乎支持所有常用語言甸箱,比如 Java育叁、.NET、Ruby 等芍殖。

  • 管理界面:提供了易用的用戶界面豪嗽,用戶可以監(jiān)控和管理消息 Broker 的許多方面。

  • 跟蹤機(jī)制:如果消息異常豌骏,RabbitMQ 提供了消息的跟蹤機(jī)制龟梦。

  • 插件機(jī)制:提供了許多插件,來從多方面進(jìn)行擴(kuò)展窃躲,也可以編輯自己的插件计贰。

2、組件結(jié)構(gòu)

RabbitMQ 組件架構(gòu)圖
  • Broker:標(biāo)識消息隊列服務(wù)器實體蒂窒。

  • Virtual Host:虛擬主機(jī)躁倒,標(biāo)識一批交換機(jī)荞怒、消息隊列和相關(guān)對象。虛擬主機(jī)是共享相同的身份認(rèn)證和加密環(huán)境的獨立服務(wù)器域秧秉。每個 vhost 本質(zhì)上就是一個的 RabbitMQ 服務(wù)器的實例褐桌,擁有自己的隊列、交換器象迎、綁定和權(quán)限機(jī)制荧嵌。vhost 是 AMQP 概念的基礎(chǔ),必須在鏈接時指定砾淌,RabbitMQ 默認(rèn)的 vhost 是【/】啦撮。

  • Exchange:交換器,用來接收生產(chǎn)者發(fā)送的消息并將這些消息路由給服務(wù)器中的隊列拇舀。

  • Queue:消息隊列逻族,用來保存消息直到發(fā)送給消費者。它是消息的容器骄崩,也是消息的終點聘鳞。一個消息可投入一個或多個隊列。消息一直在隊列里面要拂,等待消費者連接到這個隊列將其取走抠璃。

  • Banding:綁定,用于消息隊列和交換機(jī)之間的關(guān)聯(lián)脱惰。一個綁定就是基于路由鍵將交換機(jī)和消息隊列連接起來的路由規(guī)則搏嗡,所以可以將交換器理解成一個由綁定構(gòu)成的路由表。

  • Channel:信道拉一,多路復(fù)用連接中的一條獨立的雙向數(shù)據(jù)流通道采盒。信道是建立在真實的 TCP 連接內(nèi)地虛擬鏈接,AMQP 命令都是通過信道發(fā)出去的蔚润,不管是發(fā)布消息磅氨、訂閱隊列還是接收消息,這些動作都是通過信道完成嫡纠。因為對于操作系統(tǒng)來說烦租,建立和銷毀 TCP 都是非常昂貴的開銷,所以引入了信道的概念除盏,以復(fù)用一條 TCP 連接叉橱。

  • Connection:網(wǎng)絡(luò)連接,比如一個TCP連接者蠕。

  • Publisher:消息的生產(chǎn)者窃祝,也是一個向交換器發(fā)布消息的客戶端應(yīng)用程序。

  • Consumer:消息的消費者踱侣,表示一個從一個消息隊列中取得消息的客戶端應(yīng)用程序锌杀。

  • Message:消息甩栈,消息是不具名的,它是由消息頭和消息體組成糕再。消息體是不透明的量没,而消息頭則是由一系列的可選屬性組成,這些屬性包括 【routing-key(路由鍵)】突想、【priority(優(yōu)先級)】殴蹄、【delivery-mode(路由模式)】等。

3猾担、Exchange (交換器)的類型

Exchange 分發(fā)消息時袭灯,根據(jù)類型的不同分發(fā)策略有區(qū)別。常用類型包括 direct绑嘹、fanout稽荧、topic。

1)direct:

Message 中的 "路由鍵(routing-key)" 如果和 Banding 中的 "綁定鍵(binding-key)" 一致工腋,direct 類型交換器就將消息發(fā)到 Banding 對應(yīng)的 Queue 中姨丈。如下圖:

RabbitMQ direct exchange

2)fanout:

Message 都會分到所有 Banding 對應(yīng)的 Queue 中,就像子網(wǎng)廣播擅腰,每臺子網(wǎng)內(nèi)的主機(jī)都獲得了一份復(fù)制的消息蟋恬。fanout 類型的交換器轉(zhuǎn)發(fā)消息是最快的。

RabbitMQ fanout exchange

3)topic:

交換器通過模式匹配將 Message 中的 "路由鍵(routing-key)" 如果和 Banding 中的 "綁定鍵(binding-key)" 字符串切分成單詞趁冈,這些單詞之間用點隔開歼争。它同樣也會識別兩個通配符:【 # 】和 【 * 】∩保【 # 】匹配 0 個或多個單詞沐绒,【 * 】匹配一個單詞。topic 類型交換器就將消息發(fā)到 Banding 對應(yīng)的 Queue 中旺坠。

4乔遮、消息處理流程

RabbitMQ 消息處理流程

5、應(yīng)用場景

1)異步處理

場景:用戶注冊后价淌,需要發(fā)注冊郵件和注冊短信申眼。

傳統(tǒng)的做法有兩種:

  • 串行的方式
    將注冊信息寫入數(shù)據(jù)庫后瞒津,發(fā)送注冊郵件蝉衣,再發(fā)送注冊短信,以上三個任務(wù)全部完成后才返回給客戶端巷蚪。 這有一個問題是郵件病毡、短信并不是必須的,它只是一個通知屁柏,而這種做法讓客戶端等待沒有必要等待的東西啦膜。


    串行方式
  • 并行的方式
    將注冊信息寫入數(shù)據(jù)庫后有送,發(fā)送郵件的同時發(fā)送短信,以上三個任務(wù)完成后返回給客戶端僧家,并行的方式能提高處理的時間雀摘。

并行方式

假設(shè)三個業(yè)務(wù)節(jié)點分別使用50ms,串行方式使用時間150ms八拱,并行使用時間100ms阵赠。雖然并性已經(jīng)提高的處理時間,但是郵件和短信對我正常的使用網(wǎng)站沒有任何影響肌稻,客戶端沒有必要等著其發(fā)送完成才顯示注冊成功,英愛是寫入數(shù)據(jù)庫后就返回清蚀。

消息隊列方式:

引入消息隊列后,把發(fā)送郵件爹谭,短信不是必須的業(yè)務(wù)邏輯異步處理枷邪。


image

由此可以看出,引入消息隊列后诺凡,用戶的響應(yīng)時間就等于寫入數(shù)據(jù)庫的時間+寫入消息隊列的時間(可以忽略不計),

引入消息隊列后處理后东揣,響應(yīng)時間是串行的3倍,是并行的2倍绑洛。

2)應(yīng)用解耦

場景:用戶下單后救斑,訂單系統(tǒng)需要通知庫存系統(tǒng)。

傳統(tǒng)的做法就是訂單系統(tǒng)調(diào)用庫存系統(tǒng)的接口:


image

這種做法有一個缺點:當(dāng)庫存系統(tǒng)出現(xiàn)故障時真屯,訂單就會失敗脸候,訂單系統(tǒng)和庫存系統(tǒng)高耦合。

消息隊列方式:

image

訂單系統(tǒng):用戶下單后绑蔫,訂單系統(tǒng)完成持久化處理运沦,將消息寫入消息隊列,返回用戶訂單下單成功配深。
庫存系統(tǒng):訂閱下單的消息携添,獲取下單消息進(jìn)行庫操作。
就算庫存系統(tǒng)出現(xiàn)故障篓叶,消息隊列也能保證消息的可靠投遞烈掠,不會導(dǎo)致消息丟失。

3)流量削峰

場景: 因為流量過大缸托,導(dǎo)致應(yīng)用掛掉左敌,為了解決這個問題,一般在應(yīng)用前端加入消息隊列俐镐。
作用:

  • 可以控制活動人數(shù)矫限,超過此一定閥值的訂單直接丟棄。
  • 可以緩解短時間的高流量壓垮應(yīng)用(應(yīng)用程序按自己的最大處理能力獲取訂單)。


    image

用戶的請求叼风,服務(wù)器收到之后取董,首先寫入消息隊列,加入消息隊列長度超過最大值无宿,則直接拋棄用戶請求或跳轉(zhuǎn)到錯誤頁面茵汰。業(yè)務(wù)根據(jù)消息隊列中的請求信息,再做后續(xù)處理孽鸡。


2.RabbitMQ 單點安裝和配置

1经窖、安裝 EPEL 的 Yum 源。RabbitMQ 依賴于 EPEL 中的 Erlang 平臺運行梭灿。

使用文本編輯器創(chuàng)建倉庫配置文件:

[centos@host ~ ]$ sudo gedit /etc/yum.repos.d/epel.repo

在文件中編寫以下內(nèi)容并保存:

[epel-modular]
name=Extra Packages for Enterprise Linux Modular $releasever - $basearch
baseurl=http://mirrors.aliyun.com/epel/$releasever/Modular/$basearch
enabled=1
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-8

[epel]
name=Extra Packages for Enterprise Linux $releasever - $basearch
baseurl=http://mirrors.aliyun.com/epel/$releasever/Everything/$basearch
enabled=1
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-8

更新 Yum 源:

[centos@host ~]$ sudo dnf clean all
[centos@host ~]$ sudo dnf makecache
Extra Packages for Enterprise Linux Modular 8 - 429 kB/s | 118 kB     00:00    
Extra Packages for Enterprise Linux 8 - x86_64  3.7 MB/s | 6.9 MB     00:01    
元數(shù)據(jù)緩存已建立画侣。

EPEL(Extra Packages for Enterprise Linux)是企業(yè)級 Linux 操作系統(tǒng)的擴(kuò)展包倉庫,為 Redhat/CentOS系統(tǒng)提供大量的額外軟件包堡妒。

2配乱、安裝 RabbitMQ 的 Yum 源。

使用文本編輯器創(chuàng)建倉庫配置文件:

[centos@host ~]$ sudo gedit /etc/yum.repos.d/rabbitmq.repo

在文件中編寫以下內(nèi)容并保存:

[rabbitmq-server]
name=RabbitMQ Server for Redhat Linux $releasever
baseurl=https://dl.bintray.com/rabbitmq/rpm/rabbitmq-server/v3.8.x/el/$releasever/
gpgcheck=0
repo_gpgcheck=0
enabled=1
gpgkey=https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc

更新 Yum 源:

[centos@host ~]$ sudo dnf clean all
[centos@host ~]$ sudo dnf makecache
RabbitMQ Server                                 1.4 kB/s |  12 kB     00:09    
元數(shù)據(jù)緩存已建立皮迟。

3搬泥、安裝 RabbitMQ Server。

[centos@host ~]$ sudo dnf install rabbitmq-server

程序指令目錄是"/usr/sbin";
程序安裝目錄是"/usr/lib/rabbitmq";
服務(wù)器程序是"/usr/bin/rabbitmq-server";
服務(wù)器控制程序是"/usr/bin/rabbitmqctl";
程序運行用戶和組是"rabbitmq:rabbitmq"伏尼,"rabbitmq"用戶和組安裝時默認(rèn)創(chuàng)建忿檩。

4、配置 RabbitMQ 服務(wù)開機(jī)自啟動爆阶。

使用文本編輯器打開"/usr/lib/systemd/system/rabbitmq-server.service"文件:

[centos@host ~]$ sudo gedit /usr/lib/systemd/system/rabbitmq-server.service

驗證或修改文件內(nèi)容并保存:

[Unit]
Description=RabbitMQ broker
After=syslog.target network.target

[Service]
Type=notify
User=rabbitmq
Group=rabbitmq
UMask=0027
NotifyAccess=all
TimeoutStartSec=600

# To override LimitNOFILE, create the following file:
#
# /etc/systemd/system/rabbitmq-server.service.d/limits.conf
#
# with the following content:
#
# [Service]
# LimitNOFILE=65536

LimitNOFILE=32768

# Note: systemd on CentOS 7 complains about in-line comments,
# so only append them here
#
# Restart:
# The following setting will automatically restart RabbitMQ
# in the event of a failure. systemd service restarts are not a
# replacement for service monitoring. Please see
# https://www.rabbitmq.com/monitoring.html
Restart=on-failure
RestartSec=10
WorkingDirectory=/var/lib/rabbitmq
ExecStart=/usr/sbin/rabbitmq-server
ExecStop=/usr/sbin/rabbitmqctl shutdown
# See rabbitmq/rabbitmq-server-release#51
SuccessExitStatus=69

[Install]
WantedBy=multi-user.target

5燥透、啟動 RabbitMQ 服務(wù),并設(shè)置為開機(jī)自動啟動辨图。

[centos@host ~]$ sudo systemctl daemon-reload
[centos@host ~]$ sudo systemctl start rabbitmq-server.service
[centos@host ~]$ sudo systemctl enable rabbitmq-server.service

6班套、使用 RabbitMQ 管理工具【rabbitmqctl】初始化管理員用戶」屎樱【rabbitmqctl】指令只能有 root 和 rabbitmq 用戶使用吱韭。

1)創(chuàng)建新用戶:

[centos@host ~]$ sudo -u rabbitmq rabbitmqctl add_user admin password
Adding user "admin" ...

【add_user】表示創(chuàng)新以一個新用戶,格式為: add_user <用戶名> <用戶口令>

2)設(shè)置用戶角色:

[centos@host ~]$ sudo -u rabbitmq rabbitmqctl set_user_tags admin administrator
Setting tags for user "admin" to [administrator] ...

【set_user_tags】表示設(shè)置用戶的角色鱼的,格式為: set_user_tags <用戶名> <角色名>理盆。"administrator" 是內(nèi)置的超級管理員。
內(nèi)置角色有:
management :訪問 management plugin凑阶;
policymaker :訪問 management plugin 和管理自己 vhosts 的策略和參數(shù)猿规;
monitoring :訪問 management plugin 和查看所有配置和通道以及節(jié)點信息;
administrator :一切權(quán)限晌砾;
none :無配置坎拐。

3)設(shè)置用戶權(quán)限:

[centos@host ~]$ sudo -u rabbitmq rabbitmqctl set_permissions -p / admin '.*' '.*' '.*'
Setting permissions for user "admin" in vhost "/" ...

【set_permissions】表示設(shè)置用戶的訪問權(quán)限烦磁,格式為: set_permissions [-p <vhost>] <user> <conf> <write> <read>养匈。RabbitMQ 默認(rèn)的 "<vhost>" 是 "/" 哼勇,"<user>" 表示用戶名,"<conf>"呕乎、"<write>"积担、"<read>"的位置分別用正則表達(dá)式來匹配特定的資源,【'.*'】匹配所有資源猬仁,【'^$'】不匹配任何資源帝璧。

7、使用 RabbitMQ 管理工具【rabbitmq-plugins】啟用 RabbitMQ 可視化管理插件湿刽〉乃福【rabbitmq-plugins】指令只能有 root 和 rabbitmq 用戶使用。

[centos@host ~]$ sudo -u rabbitmq rabbitmq-plugins enable rabbitmq_management

8诈闺、設(shè)置防火墻端口(CentOS8默認(rèn)安裝firewall防火墻)渴庆,允許 "15672"、"25672"雅镊、"5672" 襟雷、"4369" 端口(RabbitMQ 默認(rèn)的 Http 管理插件、Erlang 訂閱仁烹、AMQP耸弄、Epmd 端口)訪問服務(wù)器。

[centos@host ~]$ sudo firewall-cmd --zone=public --add-port=15672/tcp --permanent
[centos@host ~]$ sudo firewall-cmd --zone=public --add-port=25672/tcp --permanent
[centos@host ~]$ sudo firewall-cmd --zone=public --add-port=5672/tcp --permanent
[centos@host ~]$ sudo firewall-cmd --zone=public --add-port=4369/tcp --permanent
[centos@host ~]$ sudo firewall-cmd --reload

9卓缰、驗證 RabbitMQ 可視化管理插件正常運行计呈。使用瀏覽器客戶端訪問 RabbitMQ 可視化管理插件的 Http 服務(wù)接口進(jìn)行測試,輸入:http://<IP>:<PORT>

RabbitMQ 可視化管理插件-用戶認(rèn)證
RabbitMQ 可視化管理插件-主界面

3.RabbitMQ 普通集群

普通集群模式中征唬,所有節(jié)點的 RabbitMQ 實例會同步 Virtual Host震叮、Exchange、Queue鳍鸵、Banding苇瓣、User 等內(nèi)部元數(shù)據(jù),但消息的實體數(shù)據(jù)只存儲在生產(chǎn)者連接的節(jié)點上偿乖。

假設(shè)一個普通集群由 MQ01 击罪、MQ02、MQ03 三個節(jié)點組成贪薪。生產(chǎn)者通過連接 MQ01 創(chuàng)建了一個消息媳禁,那這個消息的實體數(shù)據(jù)存儲在 MQ01 節(jié)點上;當(dāng)消費者通過連接 MQ02 或 MQ03 獲取這個消息時画切,集群會根據(jù)各節(jié)點上一致的元數(shù)據(jù)信息竣稽,將請求從 MQ02 或 MQ03 調(diào)度到 MQ01 上,從 MQ01 獲取消息。若 MQ01 故障毫别,MQ02 和 MQ03 都無法獲取消息娃弓。

3.1 集群部署拓?fù)鋱D

普通集群拓?fù)鋱D

網(wǎng)絡(luò)資源規(guī)劃:

節(jié)點名 主機(jī)名 IP:PORT 程序 操作系統(tǒng)
主節(jié)點 MQ-M 192.168.0.20:15672 / 25672 / 5672 / 4369 RabbitMQ CentOS8
備節(jié)點≥1 MQ-S1 192.168.0.21:15672 / 25672 / 5672 / 4369 RabbitMQ CentOS8

3.2 普通集群部署

1、參照章節(jié) "2.RabbitMQ 單點安裝和配置" 在主備節(jié)點上安裝 RabbitMQ 中間件岛宦。

2台丛、將主節(jié)點的 "/var/lib/rabbitmq/.erlang.cookie" 文件內(nèi)容同步覆蓋到各個備節(jié)點上,使集群中所有節(jié)點的 "erlang.cookie" 文件內(nèi)容一致砾肺。

1)查看主節(jié)點的 "erlang.cookie" 文件內(nèi)容:

[centos@MQ-M ~]$ sudo cat /var/lib/rabbitmq/.erlang.cookie
VFZZCQIEEVUVALAAUUGF

2)修改備節(jié)點的 "erlang.cookie" 文件內(nèi)容:

使用文本編輯器打開配置文件:

[centos@MQ-S1 ~]$ sudo gedit /var/lib/rabbitmq/.erlang.cookie

修改文件內(nèi)容與主節(jié)點的 "erlang.cookie" 文件內(nèi)容一致并保存:

VFZZCQIEEVUVALAAUUGF

3挽霉、設(shè)置主備節(jié)點的本地 DNS 配置文件。為集群所有節(jié)點的 IP 和 主機(jī)名建立域名映射变汪。

以集群 "主節(jié)點" 為例:

使用文本編輯器打開配置文件:

[centos@MQ-M ~]$ sudo gedit /etc/hosts

在文件中追加以下參數(shù)并保存:

192.168.0.20    MQ-M
192.168.0.21    MQ-S1

4侠坎、主備節(jié)點配置 RabbitMQ 服務(wù)開機(jī)自啟動。單點安裝時以配置開機(jī)啟動服務(wù)裙盾,集群啟動時需要修改服務(wù)文件的 "ExecStart" 參數(shù)硅蹦。

以集群 "主節(jié)點" 為例:

使用文本編輯器打開"/usr/lib/systemd/system/rabbitmq-server.service"文件:

[centos@MQ-M ~]$ sudo gedit /usr/lib/systemd/system/rabbitmq-server.service

修改文件內(nèi)容并保存:

[Unit]
Description=RabbitMQ broker
After=syslog.target network.target

[Service]
Type=notify
User=rabbitmq
Group=rabbitmq
UMask=0027
NotifyAccess=all
TimeoutStartSec=600

# To override LimitNOFILE, create the following file:
#
# /etc/systemd/system/rabbitmq-server.service.d/limits.conf
#
# with the following content:
#
# [Service]
# LimitNOFILE=65536

LimitNOFILE=32768

# Note: systemd on CentOS 7 complains about in-line comments,
# so only append them here
#
# Restart:
# The following setting will automatically restart RabbitMQ
# in the event of a failure. systemd service restarts are not a
# replacement for service monitoring. Please see
# https://www.rabbitmq.com/monitoring.html
Restart=on-failure
RestartSec=10
WorkingDirectory=/var/lib/rabbitmq
ExecStart=/usr/sbin/rabbitmq-server detached
ExecStop=/usr/sbin/rabbitmqctl shutdown
# See rabbitmq/rabbitmq-server-release#51
SuccessExitStatus=69

[Install]
WantedBy=multi-user.target

5、依序啟動主備節(jié)點的 RabbitMQ 服務(wù)闷煤。

以集群 "主節(jié)點" 為例:

[centos@MQ-M ~]$ sudo systemctl daemon-reload
[centos@MQ-M ~]$ sudo systemctl restart rabbitmq-server.service

6童芹、設(shè)置防火墻端口(CentOS8默認(rèn)安裝firewall防火墻),允許 "15672"鲤拿、"25672"假褪、"5672" 、"4369" 端口(RabbitMQ 默認(rèn)的 Http 管理插件近顷、Erlang 訂閱生音、AMQP、Epmd 端口)訪問服務(wù)器窒升。

以集群 "主節(jié)點" 為例:

[centos@MQ-M ~]$ sudo firewall-cmd --zone=public --add-port=15672/tcp --permanent
[centos@MQ-M ~]$ sudo firewall-cmd --zone=public --add-port=25672/tcp --permanent
[centos@MQ-M ~]$ sudo firewall-cmd --zone=public --add-port=5672/tcp --permanent
[centos@MQ-M ~]$ sudo firewall-cmd --zone=public --add-port=4369/tcp --permanent
[centos@MQ-M ~]$ sudo firewall-cmd --reload

7缀遍、將備節(jié)點關(guān)聯(lián)到主節(jié)點的組建集群。

備節(jié)點關(guān)聯(lián)到集群中的方式有 "磁盤節(jié)點" 和 "內(nèi)存節(jié)點" 兩種方式饱须,默認(rèn)為 "磁盤節(jié)點"域醇。"內(nèi)存節(jié)點" 將所有的隊列,交換器蓉媳,綁定關(guān)系譬挚,用戶,權(quán)限酪呻,和 vhost 的元數(shù)據(jù)信息保存在內(nèi)存中减宣。而 "磁盤節(jié)點" 將這些信息保存在磁盤中,但是內(nèi)存節(jié)點的性能更高玩荠,為了保證集群的高可用性漆腌,必須保證集群中有兩個以上的磁盤節(jié)點贼邓,來保證當(dāng)有一個磁盤節(jié)點崩潰了,集群還能對外提供訪問服務(wù)闷尿。

1)磁盤節(jié)點

[centos@MQ-S1 ~]$ sudo -u rabbitmq rabbitmqctl stop_app 
Stopping rabbit application on node rabbit@MQ-S1 ...

[centos@MQ-S1 ~]$ sudo -u rabbitmq rabbitmqctl reset
Resetting node rabbit@MQ-S1 ...

[centos@MQ-S1 ~]$ sudo -u rabbitmq rabbitmqctl join_cluster rabbit@MQ-M
Clustering node rabbit@MQ-S1 rabbit@MQ-M

[centos@MQ-S1 ~]$ sudo -u rabbitmq rabbitmqctl start_app 
Starting node rabbit@MQ-S1 ...

2)內(nèi)存節(jié)點

[centos@MQ-S1 ~]$ sudo -u rabbitmq rabbitmqctl stop_app 
Stopping rabbit application on node rabbit@MQ-S1 ...

[centos@MQ-S1 ~]$ sudo -u rabbitmq rabbitmqctl reset
Resetting node rabbit@MQ-S1 ...

[centos@MQ-S1 ~]$ sudo -u rabbitmq rabbitmqctl join_cluster rabbit@MQ-M --ram
Clustering node rabbit@MQ-S1 rabbit@MQ-M

[centos@MQ-S1 ~]$ sudo -u rabbitmq rabbitmqctl start_app
Starting node rabbit@MQ-S1 ...

8塑径、依序查看主備節(jié)點的自身狀態(tài)和集群狀態(tài)。

以集群 "主節(jié)點" 為例:

[centos@MQ-M ~]$ sudo -u rabbitmq rabbitmqctl status
[centos@MQ-M ~]$ sudo -u rabbitmq rabbitmqctl cluster_status

9悠砚、通過 RabbitMQ 可視化管理插件驗證集群。使用瀏覽器客戶端訪問 RabbitMQ 可視化管理插件的 Http 服務(wù)接口進(jìn)行測試堂飞,輸入:http://<IP>:<PORT>灌旧。

集群狀態(tài)

4.RabbitMQ 鏡像集群

鏡像集群模式中,所有節(jié)點的 RabbitMQ 實例會同步內(nèi)部元數(shù)據(jù)消息的實體數(shù)據(jù)绰筛。

假設(shè)一個鏡像集群由 MQ01 枢泰、MQ02、MQ03 三個節(jié)點組成铝噩。生產(chǎn)者通過連接 MQ01 創(chuàng)建了一個消息衡蚂,那這個消息的實體數(shù)據(jù)會同時存儲到 MQ01 、MQ02骏庸、MQ03 上毛甲,消費者通過連接 MQ02 或 MQ03 可以直接獲取到這個消息。若 MQ01 故障具被,MQ02 和 MQ03 仍然可以獲取消息玻募,具有很強(qiáng)的可靠性,但是相對于普通集群會消耗掉更多的存儲空間和帶寬一姿。比較適用于可靠性需求較高的業(yè)務(wù)場景七咧。

4.1 集群部署拓?fù)鋱D

鏡像集群拓?fù)鋱D

網(wǎng)絡(luò)資源規(guī)劃:

節(jié)點名 主機(jī)名 IP:PORT 程序 操作系統(tǒng)
主節(jié)點 MQ-M 192.168.0.20:15672 / 25672 / 5672 / 4369 RabbitMQ CentOS8
備節(jié)點≥1 MQ-S1 192.168.0.21:15672 / 25672 / 5672 / 4369 RabbitMQ CentOS8

4.2 鏡像集群部署

1、參照章節(jié) "2.RabbitMQ 單點安裝和配置" 在主備節(jié)點上安裝 RabbitMQ 中間件叮叹。

2艾栋、參照章節(jié) "3.RabbitMQ 普通集群" 部署 RabbitMQ 普通集群。

3蛉顽、將普通集群升級為鏡像集群蝗砾。

RabbitMQ 通過在集群上設(shè)置策略實現(xiàn)匹配對象的消息同步,可以通過指令和可視化管理插件設(shè)置携冤。

1)指令設(shè)置:

指令格式如下:

./rabbitmqctl set_policy <name> [-p <vhost>] <pattern> <definition> [--apply-to <apply-to>]
  • name: 策略名稱遥诉。
  • vhost: 指定 vhost , 默認(rèn)值【 / 】。
  • pattern: 匹配對象的正則表達(dá)式噪叙,【 ^ 】代表全部匹配度宦。
  • definition: 匹配模式,通過 JSON 字符串設(shè)置揣炕,如: '{"ha-mode":"all"}'族阅。其中:
    ① "ha-mode" 指明鏡像隊列的模式债朵,有效值為 "all/exactly/nodes"。"all" 表示在集群所有的節(jié)點上進(jìn)行鏡像瀑凝,無需設(shè)置 "ha-params"序芦;"exactly" 表示在指定個數(shù)的節(jié)點上進(jìn)行鏡像,節(jié)點的個數(shù)由 "ha-params"指定粤咪; " nodes" 表示在指定的節(jié)點上進(jìn)行鏡像谚中,節(jié)點名稱通過 "ha-params" 指定;
    ② "ha-params" 指明 "ha-mode" 模式需要用到的參數(shù)寥枝;
    ③ "ha-sync-mode"指明鏡像隊列中消息的同步方式宪塔,有效值為 "automatic/manually"。
  • apply-to: 匹配的對象囊拜,默認(rèn)【 all 】代表全部匹配某筐。其中:
    ① "exchanges" 表示匹配交換器;
    ② "queues" 表示匹配隊列冠跷;
    ③ "all" 表示同時匹配交換器和隊列南誊。

設(shè)置集群中所有的對象為鏡像模式,在集群 "主節(jié)點" (或者任意已經(jīng)加入集群的節(jié)點)上執(zhí)行以下指令:

[centos@MQ-M ~]$ sudo -u rabbitmq rabbitmqctl set_policy replall -p / '^' '{"ha-mode":"all"}' --apply-to all
Setting policy "replall" for pattern "^" to "{"ha-mode":"all"}" with priority "0" for vhost "/" ...

2)可視化插件設(shè)置:

在集群中創(chuàng)建消息同步策略

5.RabbitMQ 鏡像集群+ Keepalived 高可用

5.1 集群部署拓?fù)鋱D

高可用鏡像集群拓?fù)鋱D

網(wǎng)絡(luò)資源規(guī)劃:

1蜜托、RabbitMQ 集群:

節(jié)點名 主機(jī)名 IP:PORT 程序 操作系統(tǒng)
主節(jié)點 MQ-M 192.168.0.20:15672 / 25672 / 5672 / 4369 RabbitMQ CentOS8
備節(jié)點≥1 MQ-S1 192.168.0.21:15672 / 25672 / 5672 / 4369 RabbitMQ CentOS8

2抄囚、Keepalived 高可用虛擬 IP 是【192.168.0.30】。

5.2 高可用鏡像集群部署

1橄务、參照章節(jié) "2.RabbitMQ 單點安裝和配置" 在主備節(jié)點上安裝 RabbitMQ 中間件怠苔。

2、參照章節(jié) "3.RabbitMQ 普通集群" 部署 RabbitMQ 普通集群仪糖。

3柑司、參照章節(jié) "3.RabbitMQ 鏡像集群" 將普通集群升級為鏡像集群。

在各個集群節(jié)點(MQ-M 锅劝、MQ-S1 )上安裝攒驰、配置 Keepalived。以集群 "主節(jié)點" 為例:

4故爵、安裝 EPEL 的 Yum 源玻粪。

使用文本編輯器創(chuàng)建倉庫配置文件:

[centos@MQ-M ~ ]$ sudo gedit /etc/yum.repos.d/epel.repo

在文件中編寫以下內(nèi)容并保存:

[epel-modular]
name=Extra Packages for Enterprise Linux Modular $releasever - $basearch
baseurl=http://mirrors.aliyun.com/epel/$releasever/Modular/$basearch
enabled=1
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-8

[epel]
name=Extra Packages for Enterprise Linux $releasever - $basearch
baseurl=http://mirrors.aliyun.com/epel/$releasever/Everything/$basearch
enabled=1
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-8

更新 Yum 源:

[centos@Proxy-1 ~]$ sudo dnf clean all
[centos@Proxy-1 ~]$ sudo dnf makecache
Extra Packages for Enterprise Linux Modular 8 - 429 kB/s | 118 kB     00:00    
Extra Packages for Enterprise Linux 8 - x86_64  3.7 MB/s | 6.9 MB     00:01    
元數(shù)據(jù)緩存已建立。

EPEL(Extra Packages for Enterprise Linux)是企業(yè)級 Linux 操作系統(tǒng)的擴(kuò)展包倉庫诬垂,為 Redhat/CentOS系統(tǒng)提供大量的額外軟件包劲室。

5、安裝 Keepalived结窘。

[centos@MQ-M ~]$ sudo dnf install keepalived

程序安裝目錄是"/usr/sbin"很洋,配置文件目錄是"/etc/keepalived"。

6隧枫、設(shè)置 Keepalived 配置文件參數(shù)喉磁。

使用文本編輯器打開配置文件:

[centos@MQ-M ~ ]$ sudo gedit /etc/keepalived/keepalived.conf

在文件中編寫以下內(nèi)容并保存:

# 定義全局配置
global_defs {
    # 本地節(jié)點 ID 標(biāo)識谓苟,一般設(shè)置為主機(jī)名。
    router_id MQ-M
}

# 定義周期性執(zhí)行的腳本协怒,腳本的退出狀態(tài)碼會被調(diào)用它的所有的 vrrp_instance 記錄涝焙。
vrrp_script chk_rabbitmq {
    # 執(zhí)行腳本的路徑。
    script "/etc/keepalived/rabbitmq_check.sh"
    # 腳本執(zhí)行的間隔(單位是秒)孕暇。默認(rèn)為1s仑撞。
    interval 2
    # 當(dāng)腳本調(diào)整優(yōu)先級,從 -254 到 254妖滔。默認(rèn)為2隧哮。
    # 1. 如果腳本執(zhí)行成功(退出狀態(tài)碼為0),weight大于0铛楣,則priority增加近迁。
    # 2. 如果腳本執(zhí)行失敗(退出狀態(tài)碼為非0)艺普,weight小于0簸州,則priority減少。
    # 3. 其他情況下歧譬,priority不變岸浑。
    weight -20
    # 當(dāng)腳本執(zhí)行超過時長(單位是秒)則被認(rèn)為執(zhí)行失敗。
    # 運行腳本的用戶和組瑰步。
    user root root
    # timeout 30
    # 當(dāng)腳本執(zhí)行成功到設(shè)定次數(shù)時矢洲,才認(rèn)為是成功。
    # rise 1
    # 當(dāng)腳本執(zhí)行失敗到設(shè)定次數(shù)時缩焦,才認(rèn)為是失敗读虏。
    # fall 3
}

# 定義虛擬路由,可以定義多個袁滥。
vrrp_instance VI_1 {
    # 本地節(jié)點初始狀態(tài)盖桥,包括 MASTER(主節(jié)點) 和 BACKUP (備節(jié)點)。
    state MASTER
    # 本地節(jié)點綁定虛擬 IP 的網(wǎng)絡(luò)接口题翻。
    interface ens33
    # 本地節(jié)點優(yōu)先級揩徊,優(yōu)先級高的節(jié)點將動態(tài)變成 MASTER 節(jié)點,接管 VIP 嵌赠。初始狀態(tài)下塑荒,MASTER 節(jié)點的優(yōu)先級必須高于 BACKUP 節(jié)點。
    priority 100
    # VRRP 實例 ID姜挺,范圍是0-255齿税。同一集群的所有節(jié)點應(yīng)設(shè)置一致的值。
    virtual_router_id 216
    # 組播信息發(fā)送時間間隔炊豪。同一集群的所有節(jié)點必須設(shè)置一樣偎窘,默認(rèn)為1秒乌助。
    advert_int 1
    # 設(shè)置驗證信息。同一集群的所有節(jié)點必須一致
    authentication {
        # 指定認(rèn)證方式陌知。PASS 表示簡單密碼認(rèn)證(推薦)他托;AH:IPSEC認(rèn)證(不推薦)。
        auth_type PASS
        # 指定認(rèn)證所使用的密碼仆葡,最多8位赏参。
        auth_pass 1111
    }

    # 聲明調(diào)用已定義的 vrrp_script 腳本。
    track_script {
        chk_rabbitmq
    }

    # 定義虛擬 IP 地址沿盅。
    virtual_ipaddress {
        192.168.0.30
    }
}

# 定義對外提供服務(wù) LVS (負(fù)載均衡)的 VIP 和 端口(當(dāng)端口號設(shè)置為【0】時把篓,表示所有端口),只實現(xiàn)高可用時可不配置腰涧。
virtual_server 192.168.0.30 5672 {  
    # 設(shè)置健康檢查時間韧掩,單位是秒
    delay_loop 6 
    #負(fù)載均衡調(diào)度算法
    lb_algo rr
    # 設(shè)置LVS實現(xiàn)負(fù)載的機(jī)制,有NAT窖铡、TUN疗锐、DR三個模式    
    lb_kind DR
    # VIP 子網(wǎng)掩碼
    nat_mask 255.255.255.0
    # 會話保持時間,一定時間之內(nèi)用戶無響應(yīng)則下一次用戶請求時需重新路由,一般設(shè)為0费彼,表示不需要    
    persistence_timeout 0
    # 網(wǎng)絡(luò)協(xié)議
    protocol TCP
    # 定義后端 RealServer 的真實服務(wù)器屬性滑臊,IP 地址和端口(當(dāng)端口號設(shè)置為【0】時,表示所有端口)
    real_server 192.168.0.20 5672 { 
        # 配置節(jié)點權(quán)值箍铲,數(shù)字越大權(quán)重越高 
        weight 1
        TCP_CHECK {  
            connect_timeout 10         
            nb_get_retry 3  
            delay_before_retry 3  
            connect_port 80  
        }  
    }  
    real_server 192.168.0.21 5672 {
        weight 1
        TCP_CHECK {  
            connect_timeout 10  
            nb_get_retry 3  
            delay_before_retry 3  
            connect_port 80  
        }  
    }  
}

初始化的主節(jié)點和備節(jié)點的區(qū)別體現(xiàn)在以下參數(shù)中:

  • 初始主節(jié)點
vrrp_instance VI_1 {
    # 必須設(shè)置為 MASTER 雇卷。
    state MASTER
    # 必須設(shè)置為最大值。
    priority 100
}
  • 初始備節(jié)點
vrrp_instance VI_1 {
    # 必須設(shè)置為 BACKUP 颠猴。
    state BACKUP
    # 必須設(shè)置為小于主節(jié)點的值关划。
    priority 90
}

7、創(chuàng)建或編輯 RabbitMQ 檢測腳本文件翘瓮。文件路徑對應(yīng)配置文件中 vrrp_script 的 script 設(shè)置值贮折。

使用文本編輯器創(chuàng)建腳本文件:

[centos@MQ-M ~ ]$ sudo gedit /etc/keepalived/rabbitmq_check.sh

在腳本文件中編寫以下內(nèi)容并保存:

#!/bin/bash
counter=$(/usr/sbin/rabbitmqctl node_health_check | grep 'Health check passed' | wc -l)
if [ "${counter}" = "0" ]; then
    sudo -u rabbitmq /usr/sbin/rabbitmq-server detached
    sleep 5
    counter=$(/usr/sbin/rabbitmqctl node_health_check | grep 'Health check passed' | wc -l)
    if [ "${counter}" = "0" ]; then
        killall -9 keepalived
    fi
fi

給腳本文件增加可執(zhí)行權(quán)限:

[centos@MQ-M ~ ]$ sudo chmod 755 /etc/keepalived/rabbitmq_check.sh

8、配置 Keepalived 系統(tǒng)服務(wù)春畔。

使用文本編輯器創(chuàng)建配置文件:

[centos@MQ-M ~ ]$ sudo gedit /usr/lib/systemd/system/keepalived.service

驗證或修改文件內(nèi)容并保存如下:

[Unit]
Description=LVS and VRRP High Availability Monitor
After=network-online.target syslog.target rabbitmq-server.service
Wants=network-online.target
Requires=rabbitmq-server.service

[Service]
Type=forking
User=root
Group=root
PIDFile=/var/run/keepalived.pid
KillMode=process
EnvironmentFile=-/etc/sysconfig/keepalived
ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

重新加載系統(tǒng)服務(wù)管理器:

[centos@MQ-M ~ ]$ sudo systemctl daemon-reload

9脱货、設(shè)置防火墻端口(CentOS8默認(rèn)安裝firewall防火墻),允許"112"端口(Keepalived 默認(rèn)端口)訪問服務(wù)器律姨。

[centos@MQ-M ~ ]$ sudo firewall-cmd --zone=public --add-port=112/tcp --permanent
[centos@MQ-M ~ ]$ sudo firewall-cmd --reload

10振峻、啟動/重啟 Keepalived 服務(wù)(不建議設(shè)置為開機(jī)自啟動)。

啟動 Keepalived 服務(wù)之前择份,應(yīng)確保已正確啟動了各節(jié)點的 RabbitMQ 服務(wù)扣孟。各節(jié)點的啟動或重啟的順序為:① 啟動 Keepalived 主節(jié)點;② 依次啟動 Keepalived 備節(jié)點荣赶。

[centos@MQ-M ~ ]$ sudo systemctl restart keepalived.service

11凤价、啟動 Keepalived 可能因為各種未知的原因失敗鸽斟,主要是由于引發(fā)了 SELinux 異常。有關(guān)如何解決 SELinux 引起的異常利诺,請閱讀文章《RedHat/CentOS8【SELinux】引起的安全策略問題解決方案》富蓄,文章地址【http://www.reibang.com/p/a13f974f8bae】。

注意:其他 RabbitMQ 集群節(jié)點全部需要按照以上步驟配置慢逾。

12立倍、使用瀏覽器通過虛擬 IP 訪問 RabbitMQ 服務(wù)。


6.RabbitMQ 運維管理

RabbitMQ 提供可視化插件命令管道兩種運維管理途徑侣滩。

6.1.通過可視化插件運維管理

1口注、啟動 RabbitMQ 服務(wù)。

2君珠、使用 RabbitMQ 管理工具【rabbitmqctl】初始化管理員用戶寝志。【rabbitmqctl】指令只能有 root 和 rabbitmq 用戶使用策添。

1)創(chuàng)建新用戶:

[centos@host ~]$ sudo -u rabbitmq rabbitmqctl add_user admin password
Adding user "admin" ...

【add_user】表示創(chuàng)新以一個新用戶材部,格式為: add_user <用戶名> <用戶口令>

2)設(shè)置用戶角色:

[centos@host ~]$ sudo -u rabbitmq rabbitmqctl set_user_tags admin administrator
Setting tags for user "admin" to [administrator] ...

【set_user_tags】表示設(shè)置用戶的角色,格式為: set_user_tags <用戶名> <角色名>舰攒。"administrator" 是內(nèi)置的超級管理員败富。
內(nèi)置角色有:
management :訪問 management plugin悔醋;
policymaker :訪問 management plugin 和管理自己 vhosts 的策略和參數(shù)摩窃;
monitoring :訪問 management plugin 和查看所有配置和通道以及節(jié)點信息;
administrator :一切權(quán)限芬骄;
none :無配置猾愿。

3)設(shè)置用戶權(quán)限:

[centos@host ~]$ sudo -u rabbitmq rabbitmqctl set_permissions -p / admin '.*' '.*' '.*'
Setting permissions for user "admin" in vhost "/" ...

【set_permissions】表示設(shè)置用戶的訪問權(quán)限,格式為: set_permissions [-p <vhost>] <user> <conf> <write> <read>账阻。RabbitMQ 默認(rèn)的 "<vhost>" 是 "/" 蒂秘,"<user>" 表示用戶名,"<conf>"淘太、"<write>"姻僧、"<read>"的位置分別用正則表達(dá)式來匹配特定的資源,【'.*'】匹配所有資源蒲牧,【'^$'】不匹配任何資源撇贺。

3、使用 RabbitMQ 管理工具【rabbitmq-plugins】啟用 RabbitMQ 可視化管理插件冰抢∷伤唬【rabbitmq-plugins】指令只能有 root 和 rabbitmq 用戶使用。

[centos@host ~]$ sudo -u rabbitmq rabbitmq-plugins enable rabbitmq_management

4挎扰、設(shè)置防火墻端口(CentOS8默認(rèn)安裝firewall防火墻)翠订,允許 "15672"巢音、"25672"、"5672" 尽超、"4369" 端口(RabbitMQ 默認(rèn)的 Http 管理插件官撼、Erlang 訂閱、AMQP似谁、Epmd 端口)訪問服務(wù)器歧寺。

[centos@host ~]$ sudo firewall-cmd --zone=public --add-port=15672/tcp --permanent
[centos@host ~]$ sudo firewall-cmd --zone=public --add-port=25672/tcp --permanent
[centos@host ~]$ sudo firewall-cmd --zone=public --add-port=5672/tcp --permanent
[centos@host ~]$ sudo firewall-cmd --zone=public --add-port=4369/tcp --permanent
[centos@host ~]$ sudo firewall-cmd --reload

5、驗證 RabbitMQ 可視化管理插件正常運行棘脐。使用瀏覽器客戶端訪問 RabbitMQ 可視化管理插件的 Http 服務(wù)接口進(jìn)行測試斜筐,輸入:http://<IP>:<PORT>

RabbitMQ 可視化管理插件-用戶認(rèn)證
RabbitMQ 可視化管理插件-主界面

6.2.通過命令管道運維管理

1、管理 RabbitMQ 服務(wù):

rabbitmq-server start
# 啟動服務(wù)

rabbitmq-server stop
# 停止服務(wù)

rabbitmq-server restart
# 重新啟動服務(wù)

rabbitmq-server status
# 查看服務(wù)狀態(tài)

rabbitmq-server detached
# 后臺運行服務(wù)

正確安裝 RabbitMQ 后蛀缝,程序提供【rabbitmqctl】指令顷链,可用于 RabbitMQ 服務(wù)的運維管理。

2屈梁、【rabbitmqctl】語法:

rabbitmqctl [-n <node>] [-q][-h] <command> [<command options>] 
其中:
-n <node>:默認(rèn) node 名稱是 "rabbit@hostname"嗤练,如果你的主機(jī)明是 "MQ-M",那么 node 名稱是 "rabbit@'MQ-M"在讶。
-q:安靜輸出模式煞抬,信息會被禁止輸出。
-h:查看幫助信息构哺。
command:管理指令革答。
command options:管理指令的參數(shù)。

3曙强、基本管理指令:

shutdown
# 關(guān)閉 RabbitMQ 服務(wù)残拐。

stop [<pid_file>]  
# 停止在 erlang node 上運行的 RabbitMQ。

stop_app   
# 停止 erlang node 上的 RabbitMQ 的應(yīng)用碟嘴,但是 erlang node 還是會繼續(xù)運行溪食。

start_app   
# 啟動 erlang node 上的 RabbitMQ 的應(yīng)用。

wait <pid_file>  
# 等待 RabbitMQ 服務(wù)啟動娜扇。

reset  
# 初始化 erlang node 狀態(tài)错沃,會從集群中刪除該節(jié)點,從管理數(shù)據(jù)庫中刪除所有數(shù)據(jù)雀瓢,例如:vhosts 等枢析。在初始化之前 RabbitMQ 的應(yīng)用必須先停止。

force_reset  
# 無條件的初始化 erlang node 狀態(tài)致燥。

status
# 查看 RabbitMQ 服務(wù)的狀態(tài)登疗。

rotate_logs <suffix>   
# 輪轉(zhuǎn)日志文件。

3、集群管理指令:

join_cluster <clusternode> [--ram]  
# 加入到指定主節(jié)點的集群中辐益。clusternode 表示 node 名稱断傲,--ram 表示 node 以 ram node(內(nèi)存節(jié)點) 加入集群中。默認(rèn) node 以 disc node(磁盤節(jié)點) 加入集群智政,在一個 node 加入 cluster 之前认罩,必須先停止該 node 的 RabbitMQ 應(yīng)用,即先執(zhí)行 stop_app续捂。

cluster_status  
# 顯示 cluster 中的所有 node 的狀態(tài)垦垂。

change_cluster_node_type disc | ram  
# 改變一個 cluster 中 node 的模式,該節(jié)點在轉(zhuǎn)換前必須先停止牙瓢,不能把一個集群中唯一的 disk node 轉(zhuǎn)化為 ram node劫拗。

forget_cluster_node [--offline]  
# 遠(yuǎn)程移除 cluster 中的一個 node,前提是該 node 必須處于 offline 狀態(tài)矾克,如果是 online 狀態(tài)页慷,則需要加--offline 參數(shù)。

sync_queue queue  
# 同步鏡像隊列胁附。

cancel_sync_queue queue    
# 取消同步鏡像隊列酒繁。

4、用戶管理指令:

add_user <username> <password>  
# 在 RabbitMQ 的內(nèi)部數(shù)據(jù)庫添加用戶控妻。

delete_user <username>  
# 刪除一個用戶州袒。

change_password <username> <newpassword>  
# 改變用戶密碼。

clear_password <username> 
# 清除用戶密碼弓候,禁止用戶登錄郎哭。

set_user_tags <username> <tag> ...
# 設(shè)置用戶 tags(內(nèi)置角色)。內(nèi)置角色有:
# > management :訪問 management plugin弓叛;
# > policymaker :訪問 management plugin 和管理自己 vhosts 的策略和參數(shù)彰居;
# > monitoring :訪問 management plugin 和查看所有配置和通道以及節(jié)點信息诚纸;
# > administrator :一切權(quán)限撰筷;
# > none :無配置。

list_users  
# 列出用戶畦徘。

add_vhost <vhostpath>  
# 創(chuàng)建一個 vhosts 毕籽。

delete_vhost <vhostpath>  
# 刪除一個 vhosts 。
list_vhosts [<vhostinfoitem> ...]  
# 列出 vhosts 井辆。

set_permissions [-p <vhostpath>] <user> <conf> <write> <read>  
# 針對一個 vhosts 給用戶賦予相關(guān)權(quán)限关筒。

clear_permissions [-p <vhostpath>] <username>  
# 清除一個用戶對 vhosts 的權(quán)限。

list_permissions [-p <vhostpath>]   
# 列出哪些用戶可以訪問該 vhosts杯缺。

list_user_permissions <username>  
# 列出該用戶的訪問權(quán)限蒸播。

5、策略管理指令:

set_policy [-p <vhostpath>] [--priority <priority>] [--apply-to <apply-to>]  
#  > name: 策略名稱。
#  > vhost: 指定 vhost , 默認(rèn)值【 / 】袍榆。
#  > pattern: 匹配對象的正則表達(dá)式胀屿,【 ^ 】代表全部匹配。
#  > definition: 匹配模式包雀,通過 JSON 字符串設(shè)置宿崭,如: '{"ha-mode":"all"}'。其中:
#  "ha-mode" 指明鏡像隊列的模式才写,有效值為 "all/exactly/nodes"葡兑。"all"  表示在集群所有的節(jié)點上進(jìn)行鏡像,無需設(shè)置 "ha-params"赞草;"exactly" 表示在指定個數(shù)的節(jié)點上進(jìn)行鏡像讹堤,節(jié)點的個數(shù)由 "ha-params"指定; " nodes" 表示在指定的節(jié)點上進(jìn)行鏡像厨疙,節(jié)點名稱通過 "ha-params" 指定蜕劝;
#  "ha-params" 指明 "ha-mode" 模式需要用到的參數(shù);
#  "ha-sync-mode"指明鏡像隊列中消息的同步方式轰异,有效值為 "automatic/manually"岖沛。
# > apply-to: 匹配的對象,默認(rèn)【 all 】代表全部匹配搭独。其中:
# "exchanges" 表示匹配交換器婴削;
# "queues" 表示匹配隊列;
# "all" 表示同時匹配交換器和隊列牙肝。

clear_policy [-p <vhostpath>] <name>  
# 清除一個策略唉俗。

list_policies [-p <vhostpath>]  
# 列出已有的策略。

6配椭、插件管理指令:

rabbitmq-plugins <command> [<command options>]
# Commands:
#     list [-v] [-m] [-E] [-e] [<pattern>]  顯示所有的的插件虫溜。-v 顯示版本 -m 顯示名稱 -E 顯示明確已經(jīng)開啟的 -e 顯示明確的和暗中開啟的
#     enable <plugin> ...   開啟一個插件
#     disable <plugin> ...  關(guān)閉一個插件

如:
rabbitmq-plugins enable rabbitmq_management
# 開啟可視化插件。

7股缸、其他管理指令:

list_queues [-p <vhostpath>] [<queueinfoitem> ...]  
# 返回 queue 的信息衡楞,如果省略了-p參數(shù),則默認(rèn)顯示的是【 / 】的 vhosts 信息敦姻。

list_exchanges [-p <vhostpath>] [<exchangeinfoitem> ...]  
#返回 exchange 的信息瘾境。

list_bindings [-p <vhostpath>] [<bindinginfoitem> ...] 
# 返回綁定信息。

list_connections [<connectioninfoitem> ...]  
# 返回鏈接信息镰惦。

list_channels [<channelinfoitem> ...]  
# 返回目前所有的 channels 迷守。

list_consumers [-p <vhostpath>]  
# 返回 consumers。

status  
# 顯示 broker 的狀態(tài)旺入。

environment  
# 顯示環(huán)境參數(shù)的信息兑凿。

report  
# 返回一個服務(wù)狀態(tài) report 凯力。

7.Java 開發(fā)集成示例

amqp-client 是 RabbitMQ 的 JavaAPI 包,以下是 Maven 項目的程序案例礼华。

1沮协、從 Maven 庫中引入 amqp-client 包。

<dependency>
  <groupId>com.rabbitmq</groupId>
  <artifactId>amqp-client</artifactId>
  <version>5.9.0</version>
</dependency>

2卓嫂、編寫 Producter(生產(chǎn)者)端示例程序慷暂。本示例實現(xiàn)【每隔 1 秒鐘無線循環(huán)向隊列提交一個 UUID 消息】。

import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 *  生產(chǎn)者提交消息晨雳。
 *
 */
public class Producter {
    public static void main(String[] args) {
        
        // RabbitMQ 服務(wù)地址
        String mqIp = "192.168.0.30";
        // RabbitMQ 服務(wù)端口
        int mqPort = 5672;
        // RabbitMQ 登錄賬號
        String mqUser = "admin";
        // RabbitMQ 登錄賬號口令
        String mqPass = "123456a?";

        // 定義虛擬主機(jī)
        String vhost = "/";
        // 定義交換器(如果 RabbitMQ 上沒有這個 exchange 會自動創(chuàng)建)
        String exchange = "test_exchange";
        // 定義隊列(如果 RabbitMQ 上沒有這個 queue 會自動創(chuàng)建)
        String queue = "test_queue";
        // 定義綁定KEY(如果 RabbitMQ 上沒有這個 bandingkey 會自動創(chuàng)建)
        String bandingkey = "test_bandingkey";

        // RabbitMQ Tcp 連接工廠實例行瑞。
        ConnectionFactory factory = null;
        // RabbitMQ Tcp 連接實例。
        Connection connection = null;
        // RabbitMQ 信道實例餐禁。
        Channel channel = null;

        try {
            
            // 創(chuàng)建 RabbitMQ 連接工廠
            factory = new ConnectionFactory();

            factory.setHost(mqIp);
            factory.setPort(mqPort);
            factory.setUsername(mqUser);
            factory.setPassword(mqPass);
            factory.setVirtualHost(vhost);

            // 創(chuàng)建 RabbitMQ Tcp 連接實例
            connection = factory.newConnection();
            
            // 創(chuàng)建 RabbitMQ 頻道
            channel = connection.createChannel();
            
            // 聲明交換機(jī)類型
            channel.exchangeDeclare(exchange, "fanout", true);
            
            // 聲明隊列
            channel.queueDeclare(queue, true, false, true, null);
            
            // 也可以獲取默認(rèn)隊列
            // String queue = channel.queueDeclare().getQueue();
            
            // 將隊列與交換機(jī)綁定
            channel.queueBind(queue, exchange, bandingkey);
            
            // 將數(shù)據(jù)提交到隊列血久,本例中每隔1秒鐘無線循環(huán)寫入一個 UUID 消息。
            while (true) {
                String uuid = UUID.randomUUID().toString();
                System.out.println("提交消息:" + uuid);
                channel.basicPublish(exchange, bandingkey, null, uuid.getBytes());
                Thread.sleep(1000);
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

測試運行結(jié)果:

生產(chǎn)者提交消息

2帮非、編寫 Consumer(消費者)端示例程序氧吐。本示例實現(xiàn)【從隊列中獲取已提交的 UUID 消息】。

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;

/**
 *  消費者獲取消息末盔。
 *
 */
public class Consumer {

    public static void main(String[] args) {

        // RabbitMQ 服務(wù)地址
        String mqIp = "192.168.0.30";
        // RabbitMQ 服務(wù)端口
        int mqPort = 5672;
        // RabbitMQ 登錄賬號
        String mqUser = "admin";
        // RabbitMQ 登錄賬號口令
        String mqPass = "123456a?";

        // 定義虛擬主機(jī)
        String vhost = "/";
        // 定義交換器(如果 RabbitMQ 上沒有這個 exchange 會自動創(chuàng)建)
        String exchange = "test_exchange";
        // 定義隊列(如果 RabbitMQ 上沒有這個 queue 會自動創(chuàng)建)
        String queue = "test_queue";
        // 定義綁定KEY(如果 RabbitMQ 上沒有這個 bandingkey 會自動創(chuàng)建)
        String bandingkey = "test_bandingkey";

        // RabbitMQ Tcp 連接工廠實例筑舅。
        ConnectionFactory factory = null;
        // RabbitMQ Tcp 連接實例。
        Connection connection = null;
        // RabbitMQ 信道實例陨舱。
        Channel channel = null;

        try {

            // 創(chuàng)建 RabbitMQ 連接工廠
            factory = new ConnectionFactory();

            factory.setHost(mqIp);
            factory.setPort(mqPort);
            factory.setUsername(mqUser);
            factory.setPassword(mqPass);
            factory.setVirtualHost(vhost);

            // 創(chuàng)建 RabbitMQ Tcp 連接實例
            connection = factory.newConnection();

            // 創(chuàng)建 RabbitMQ 頻道
            channel = connection.createChannel();

            // 聲明交換機(jī)類型
            channel.exchangeDeclare(exchange, "fanout", true);

            // 聲明隊列
            channel.queueDeclare(queue, true, false, true, null);

            // 也可以獲取默認(rèn)隊列
            // String queue = channel.queueDeclare().getQueue();

            // 將隊列與交換機(jī)綁定
            channel.queueBind(queue, exchange, bandingkey);

            // 從隊列獲取數(shù)據(jù)翠拣,本例中每隔1秒鐘無線循環(huán)寫入一個 UUID 消息。
            DefaultConsumer 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綁定隊列游盲、消費者误墓,autoAck為true表示一旦收到消息則自動回復(fù)確認(rèn)消息
            channel.basicConsume(queue, true, consumer);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }

    }

}

測試運行結(jié)果:

消費者獲取消息

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市益缎,隨后出現(xiàn)的幾起案子谜慌,更是在濱河造成了極大的恐慌,老刑警劉巖莺奔,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欣范,死亡現(xiàn)場離奇詭異,居然都是意外死亡弊仪,警方通過查閱死者的電腦和手機(jī)熙卡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來励饵,“玉大人,你說我怎么就攤上這事滑燃∫厶” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長典予。 經(jīng)常有香客問我甜滨,道長,這世上最難降的妖魔是什么瘤袖? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任衣摩,我火速辦了婚禮,結(jié)果婚禮上捂敌,老公的妹妹穿的比我還像新娘艾扮。我一直安慰自己,他們只是感情好占婉,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布泡嘴。 她就那樣靜靜地躺著,像睡著了一般逆济。 火紅的嫁衣襯著肌膚如雪酌予。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天奖慌,我揣著相機(jī)與錄音抛虫,去河邊找鬼。 笑死简僧,一個胖子當(dāng)著我的面吹牛莱褒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涎劈,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼广凸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蛛枚?” 一聲冷哼從身側(cè)響起谅海,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蹦浦,沒想到半個月后扭吁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡盲镶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年侥袜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片溉贿。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡枫吧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宇色,到底是詐尸還是另有隱情九杂,我是刑警寧澤颁湖,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站例隆,受9級特大地震影響甥捺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜镀层,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一镰禾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唱逢,春花似錦吴侦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绸贡,卻和暖如春盯蝴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背听怕。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工捧挺, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人尿瞭。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓闽烙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親声搁。 傳聞我的和親對象是個殘疾皇子黑竞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348