1. 程式人生 > >【SpringBoot MQ 系列】RabbitMq 核心知識點小結

【SpringBoot MQ 系列】RabbitMq 核心知識點小結

【MQ 系列】RabbitMq 核心知識點小結

以下內容,部分取材於官方教程,部分來源網路博主的分享,如有興趣瞭解更多詳細的知識點,可以在本文最後的文章列表中獲取原地址

RabbitMQ 是一個基於 AMQP 協議實現的企業級訊息系統,想要順暢的玩耍的前提是得先了解它,本文將主要介紹 rabbitmq 的一些基本知識點

  • 特點
  • 基本概念
  • 訊息投遞消費的幾種姿勢
  • 事務
  • 叢集

I. 基本知識點

它是採用 Erlang 語言實現的 AMQP(Advanced Message Queued Protocol)的訊息中介軟體,最初起源於金融系統,用在分散式系統儲存轉發訊息,目前廣泛應用於各類系統用於解耦、削峰

1.特點

首先得了解一下 rabbitmq 的特點,看看是否滿足我們的系統需求(畢竟學習一個框架也是要不少時間的)

以下內容來自: MQ 和 RabbitMQ 作用特點

主要特點,大致可以歸納為以下幾個

  • 可靠性:通過支援訊息持久化,支援事務,支援消費和傳輸的 ack 等來確保可靠性
  • 路由機制:支援主流的訂閱消費模式,如廣播,訂閱,headers 匹配等
  • 擴充套件性:多個 RabbitMQ 節點可以組成一個叢集,也可以根據實際業務情況動態地擴充套件叢集中節點。
  • 高可用性:佇列可以在叢集中的機器上設定映象,使得在部分節點出現問題的情況下隊仍然可用。
  • 多種協議:RabbitMQ 除了原生支援 AMQP 協議,還支援 STOMP,MQTT 等多種訊息中介軟體協議。
  • 多語言客戶端:RabbitMQ 幾乎支援所有常用語言,比如 Jav a、Python、Ruby、PHP、C#、JavaScript 等。
  • 管理介面:RabbitMQ 提供了一個易用的使用者介面,使得使用者可以監控和管理訊息、叢集中的節點等。
  • 外掛機制:RabbitMQ 提供了許多外掛,以實現從多方面進行擴充套件,當然也可以編寫自己的外掛。

2. 基本概念

下圖為 rabbitmq 的內部結構圖

從上圖也可以發現幾個基本概念(Message, Publisher, Exchange, Binding, Queue, Channel, Consuer, Virtual host)

下面逐一進行說明

a. Message

具體的訊息,包含訊息頭(即附屬的配置資訊)和訊息體(即訊息的實體內容)

由釋出者,將訊息推送到 Exchange,由消費者從 Queue 中獲取

b. Publisher

訊息生產者,負責將訊息釋出到交換器(Exchange)

c. Exchange

交換器,用來接收生產者傳送的訊息並將這些訊息路由給伺服器中的佇列

d. Binding

繫結,用於給 Exchange 和 Queue 建立關係,從而決定將這個交換器中的哪些訊息,傳送到對應的 Queue

e. Queue

訊息佇列,用來儲存訊息直到傳送給消費者

它是訊息的容器,也是訊息的終點

一個訊息可投入一個或多個佇列

訊息一直在佇列裡面,等待消費者連線到這個佇列將其取走

f. Connection

連線,內部持有一些 channel,用於和 queue 打交道

g. Channel

通道(通道),MQ 與外部打交道都是通過 Channel 來的,釋出訊息、訂閱佇列還是接收訊息,這些動作都是通過 Channel 完成;

簡單來說就是訊息通過 Channel 塞進佇列或者流出佇列

h. Consumer

消費者,從訊息佇列中獲取訊息的主體

i. Virtual Host

虛擬主機,表示一批交換器、訊息佇列和相關物件。

虛擬主機是共享相同的身份認證和加密環境的獨立伺服器域。

每個 vhost 本質上就是一個 mini 版的 RabbitMQ 伺服器,擁有自己的佇列、交換器、繫結和許可權機制。

vhost 是 AMQP 概念的基礎,必須在連線時指定,RabbitMQ 預設的 vhost 是 /

可以理解為 db 中的資料庫的概念,用於邏輯拆分

j. Broker

訊息佇列伺服器實體

3. 訊息投遞消費

從前面的內部結構圖可以知曉,訊息由生產者釋出到 Exchange,然後通過路由規則,分發到繫結 queue 上,供消費者獲取訊息

接下來我們看一下 Exchange 支援的四種策略

a. Direct 策略

訊息中的路由鍵(routing key)如果和 Binding 中的 binding key 一致, 交換器就將訊息發到對應的佇列中

簡單來講,就是rounting keybinding key完全匹配

  • 如果一個佇列繫結到交換機要求路由鍵為dog
  • 只轉發routing key 標記為dog的訊息,
  • 不會轉發dog.puppy,也不會轉發“dog.guard”等等
  • 它是完全匹配、單播的模式

舉例說明

Exchange 和兩個佇列繫結在一起:

  • Q1 的 bindingkey 是 orange
  • Q2 的 binding key 是 black 和 green.
  • 當 Producer 釋出一個訊息,其routing keyorange時, exchange 會把它放到 Q1 上, 如果是blackgreen就會到 Q2 上, 其餘的 Message 被丟棄

注意

  • 當有多個佇列繫結到同一個 Exchange,且 binding key 相同時,這時訊息會分發給所有滿足條件的佇列

b. Topic 策略

這個策略可以看成是 Direct 策略的升級版,通過routing keybingding key的模式匹配方式來分發訊息

簡單來講,直接策略是完全精確匹配,而 topic 則支援正則匹配,滿足某類指定規則的(如以 xxx 開頭的路由鍵),可以將訊息分發過去

  • # 匹配 0 個或多個單詞
  • * 匹配不多不少一個單詞

一個更直觀的例項如下

Producer 傳送訊息時需要設定 routing_key,

  • Q1 的 binding key 是*.orange.*
  • Q2 是 *.*.rabbitlazy.#
  • 釋出一個routing keytest.orange.mm 訊息,則會路由到 Q1;
    • 注意: 如果是routng keytest.orange則無法路由到 Q1,
    • 因為 Q1 的規則是三個單詞,中間一個為 orange,不滿足這個規則的都無效
  • 釋出一個routing keytest.qq.rabbit或者lazy.qq的訊息 都可以分發到 Q2;即路由 key 為三個單詞,最後一個為 rabbit 或者不限制單詞個數,主要第一個是 lazy 的訊息,都可以分發過來
  • 如果釋出的是一個test.orange.rabbit訊息,則 Q1 和 Q2 都可以滿足
    • 注意: 這時兩個佇列都會接受到這個訊息

c. Fanout 策略

廣播策略,忽略routing keybinding key,將訊息分發給所有繫結在這個 exchange 上的 queue

d. Headers 策略

這個實際上用得不多,它是根據 Message 的一些頭部資訊來分發過濾 Message,忽略 routing key 的屬性,如果 Header 資訊和 message 訊息的頭資訊相匹配

II. 訊息一致性問題

在進入 rabbitmq 如何保證一致性之前,我們先得理解,什麼是訊息一致性?

1. 一致性問題

資料的一致性是什麼

按照我個人的粗淺理解,我認為的訊息一致性,應該包含下面幾個

  • 生產者,確保訊息釋出成功
    • 訊息不會丟
    • 順序不會亂
    • 訊息不會重複(如重傳,導致釋出一次,卻出現多個訊息)
  • 消費者,確保訊息消費成功
    • 有序消費
    • 不重複消費

傳送端

為了確保釋出者推送的訊息不會丟失,我們需要訊息持久化

  • broker 持久化訊息

為了確定訊息正確接收

  • publisher 需要知道訊息投遞併成功持久化

2. 持久化

這裡的持久化,主要是指將記憶體中的訊息儲存到磁碟,避免 mq 宕機導致的記憶體中訊息丟失;然而單純的持久化,只是保證一致性的其中一個要素,比如 publisher 將訊息傳送到 exchange,在 broker 持久化的工程中,宕機了導致持久化失敗,而 publisher 並不知道持久化失敗,這個時候就會出現資料丟失,為了解決這個問題,rabbitmq 提供了事務機制

3. 事務機制

事務機制能夠解決生產者與 broker 之間訊息確認的問題,只有訊息成功被 broker 接受,事務才能提交成功,否則就進行事務回滾操作並進行訊息重發。但是使用事務機制會降低 RabbitMQ 的訊息吞吐量,不適用於需要釋出大量訊息的業務場景。

注意,事務是同步的

4. 訊息確認機制

RabbitMQ 學習(六)——訊息確認機制(Confirm 模式)

訊息確認機制,可以區分為生產端和消費端

生產端

  • 生產者將通道設定成 Confirm 模式,一旦通道進入 Confirm 模式,所有在該通道上面釋出的訊息都會被指派一個唯一的 ID(以 confirm.select 為基礎從 1 開始計數),
  • 一旦訊息被投遞到所有匹配的佇列之後,Broker 就會發送一個確認給生產者(包含訊息的唯一 ID),這就使得生產者知道訊息已經正確到達目的隊列了,
  • 如果訊息和佇列是可持久化的,那麼確認訊息會將訊息寫入磁碟之後發出,
  • Broker 回傳給生產者的確認訊息中 deliver-tag 域包含了確認訊息的序列號(此外 Broker 也可以設定 basic.ack 的 multiple 域,表示到這個序列號之前的所有訊息都已經得到了處理)

Confirm 模式屬性非同步,publisher 釋出一條訊息之後,在等通道返回確認的同時,依然可以繼續傳送下一條訊息,所以小概率會出現投遞的訊息順序和 broker 中持久化訊息順序不一致的問題

一般從程式設計角度出發,Confirm 模式有三種姿勢

  • 普通 Confirm 模式:傳送一條訊息之後,等到伺服器 confirm,然後再發佈下一條訊息(序列釋出)
  • 批量 Confirm 模式:傳送一批訊息之後,等到伺服器 confirm,然後再發佈下一批訊息(如果失敗,這一批訊息全部重複,所以會有重複問題)
  • 非同步 Confirm 模式:提供一個回撥方法,伺服器 confirm 之後,觸發回撥方法,因此不會阻塞下一條訊息的傳送

消費端

ACK 機制是消費者從 RabbitMQ 收到訊息並處理完成後,反饋給 RabbitMQ,RabbitMQ 收到反饋後才將此訊息從佇列中刪除。

  • 如果一個消費者在處理訊息出現了網路不穩定、伺服器異常等現象,那麼就不會有 ACK 反饋,RabbitMQ 會認為這個訊息沒有正常消費,會將訊息重新放入佇列中
  • 如果在叢集的情況下,RabbitMQ 會立即將這個訊息推送給這個線上的其他消費者。這種機制保證了在消費者服務端故障的時候,不丟失任何訊息和任務
  • 訊息永遠不會從 RabbitMQ 中刪除,只有當消費者正確傳送 ACK 反饋,RabbitMQ 確認收到後,訊息才會從 RabbitMQ 伺服器的資料中刪除

III. 叢集

按照目前的發展趨勢,一個不支援叢集的中介軟體基本上是不會有市場的;rabbitmq 也是支援叢集的,下面簡單的介紹一下常見的 4 種叢集架構模式

以下內容來自網上博文,詳情請點選右邊:RabbitMQ 的 4 種叢集架構

1. 主備模式

這個屬於常見的叢集模式了,但又不太一樣

主節點提供讀寫,備用節點不提供讀寫。如果主節點掛了,就切換到備用節點,原來的備用節點升級為主節點提供讀寫服務,當原來的主節點恢復執行後,原來的主節點就變成備用節點

2. 遠端模式

遠端模式可以實現雙活的一種模式,簡稱 shovel 模式,所謂的 shovel 就是把訊息進行不同資料中心的複製工作,可以跨地域的讓兩個 MQ 叢集互聯,遠距離通訊和複製。

  • Shovel 就是我們可以把訊息進行資料中心的複製工作,我們可以跨地域的讓兩個 MQ 叢集互聯。

如上圖,有兩個異地的 MQ 叢集(可以是更多的叢集),當用戶在地區 1 這裡下單了,系統發訊息到 1 區的 MQ 伺服器,發現 MQ 服務已超過設定的閾值,負載過高,這條訊息就會被轉到 地區 2 的 MQ 伺服器上,由 2 區的去執行後面的業務邏輯,相當於分攤我們的服務壓力。

3. 映象模式

非常經典的 mirror 映象模式,保證 100% 資料不丟失。在實際工作中也是用得最多的,並且實現非常的簡單,一般網際網路大廠都會構建這種映象叢集模式。

如上圖,用 KeepAlived 做了 HA-Proxy 的高可用,然後有 3 個節點的 MQ 服務,訊息傳送到主節點上,主節點通過 mirror 佇列把資料同步到其他的 MQ 節點,這樣來實現其高可靠

4. 多活模式

也是實現異地資料複製的主流模式,因為 shovel 模式配置比較複雜,所以一般來說,實現異地叢集的都是採用這種雙活 或者 多活模型來實現的。這種模式需要依賴 rabbitMQ 的 federation 外掛,可以實現持續的,可靠的 AMQP 資料通訊,多活模式在實際配置與應用非常的簡單

rabbitMQ 部署架構採用雙中心模式(多中心),那麼在兩套(或多套)資料中心各部署一套 rabbitMQ 叢集,各中心的 rabbitMQ 服務除了需要為業務提供正常的訊息服務外,中心之間還需要實現部分佇列訊息共享。

federation 外掛是一個不需要構建 cluster ,而在 brokers 之間傳輸訊息的高效能外掛,federation 外掛可以在 brokers 或者 cluster 之間傳輸訊息,連線的雙方可以使用不同的 users 和 virtual hosts,雙方也可以使用不同版本的 rabbitMQ 和 erlang。federation 外掛使用 AMQP 協議通訊,可以接受不連續的傳輸。federation 不是建立在叢集上的,而是建立在單個節點上的,如圖上黃色的 rabbit node 3 可以與綠色的 node1、node2、node3 中的任意一個利用 federation 外掛進行資料同步。

IV. 其他

0. 專案

  • 工程:https://github.com/liuyueyi/spring-boot-demo

1. 相關博文

  • RabbitMQ Tutorials
  • MQ 和 RabbitMQ 作用特點
  • RabbitMq 基礎教程之基本概念
  • RabbitMQ 學習(六)——訊息確認機制(Confirm 模式)
  • RabbitMQ 的 4 種叢集架構
  • Rabbitmq 是如何來保證事務的
  • rabbitmq 訊息一致性問題

2. 一灰灰 Blog

盡信書則不如,以上內容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發現 bug 或者有更好的建議,歡迎批評指正,不吝感激

下面一灰灰的個人部落格,記錄所有學習和工作中的博文,歡迎大家前去逛逛

  • 一灰灰 Blog 個人部落格 https://blog.hhui.top
  • 一灰灰 Blog-Spring 專題部落格 http://spring.hhui.top

相關推薦

SpringBoot MQ 系列RabbitMq 核心知識點小結

【MQ 系列】RabbitMq 核心知識點小結 以下內容,部分取材於官方教程,部分來源網路博主的分享,如有興趣瞭解更多詳細的知識點,可以在本文最後的文章列表中獲取原地址 RabbitMQ 是一個基於 AMQP 協議實現的企業級訊息系統,想要順暢的玩耍的前提是得先了解它,本文將主要介紹 rabbitmq

SpringBoot 基礎系列實現一個自定義配置載入器(應用篇)

![](https://spring.hhui.top/spring-blog/imgs/200507/logo.jpg) > [【SpringBoot 基礎系列】實現一個自定義配置載入器(應用篇)](https://mp.weixin.qq.com/s?__biz=MzU3MTAzNTMzMQ==&

GPU精粹與Shader程式設計(一) 開篇 & 全系列11本書核心知識點總覽

系列文章前言 《GPU Gems》1~3 、《GPU Pro》1~7 以及《GEM Zen》組成的GPU精粹系列書籍,是遊戲開發、計算機圖形學和渲染領域的業界大牛們優秀經驗的分享合輯彙編,是江湖各大武林門派絕學經典招式的精華薈萃,可謂遊戲開發、圖形學和渲染領

面試複習系列常用機器學習演算法知識點及其解析,面試官會考的幾乎都有,歡迎補充

圖片慢慢上傳,看不到圖片的請點這裡: LR:logistic regression  對數機率迴歸/邏輯迴歸 sigmoid函式的作用就是用於把輸出歸一到1和0,也就

SpringBoot基礎系列-實戰如何指定 bean 最先載入(應用篇)

![](https://spring.hhui.top/spring-blog/imgs/200317/logo.jpg) > [【基礎系列-實戰】如何指定 bean 最先載入(應用篇)](https://mp.weixin.qq.com/s?__biz=MzU3MTAzNTMzMQ==&mi

iOS開發系列九宮格布局

使用 objc with div self. orm i++ back hab /** * 這個盡管非常easy,算是一個小技巧,可是碰到了就記錄下來吧.積跬步,致千裏嘛. */ - (void)scratchableLatex { for (int i=

JVM命令系列jmap

mark bsp null 參考 nfa location bootstra 內容 遠程debug 命令基本概述 Jmap是一個可以輸出所有內存中對象的工具,甚至可以將VM 中的heap,以二進制輸出成文本。打印出某個java進程(使用pid)內存內的,所有‘對象’的情況(

iOS開發系列NSObject方法介紹

ati ber oid ring cto rgb dst -s 推斷 NSObject是OC中的基類,全部類都繼承於此,這裏面也給我們提供了非常多與“類”和“方法”相關的方法,本文將解說幾個非常有用的方法。 正文: Per

大數據系列HDFS文件權限和安全模式、安裝

重新啟動 inux 客戶 元數據 masters cnblogs 格式 新的 檢測 HDFS文件權限 1、與linux文件權限類型 r:read w:write x:execute權限x對於文件忽略,對於文件夾表示是否允許訪問其內容 2、如果linux系統用戶sanglp

大數據系列MapReduce示例好友推薦

trac [0 ont protect run task main orm pat package org.slp; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text;

大數據系列在hadoop2.8.0下配置SecondaryNameNode

hadoop .cn color dfs repl images replicat style 節點 修改namenode上的hdfs-site.xml configuration> <property> <name>dfs.r

SignalR學習系列4. SignalR廣播程序

back aspnet ocs || tutorial strong family load over 創建項目 創建一個空的 Web 項目,並在 Nuget 裏面添加 SignalR,jQuery UI 包,添加以後項目裏包含了 jQuery,jQuery.UI ,和

Owin 學習系列1. 第一個 Owin 程序

進程 task reading 地址 [] 地址欄 urn rtu () IIS 中的 Owin 在 IIS 裏面部署 Owin,既能得到 Owin 管道模型的靈活性和模塊特性,也能很好地利用 IIS 成熟的配置,Owin 程序將會跑在 ASP.NET reques

問題記錄系列the resource is not on the build path of a java project

搭建 關閉 spring源碼 remove 環境 eclips 右鍵 生產 ldp 在eclipse中新建了一個maven項目搭建Spring源碼閱讀環境,創建一個bean生產getter和setter方法的時候報錯“the resource is not on the b

表格建模系列二、添加數據

geography custom img eof pan ipaddress customer fwe ebr 加載如下表並清空相應字段: DimCustomer清除字段: SpanishEducation, FrenchEducation, SpanishOccupati

表格建模系列五、創建分區

ant ntp amt intern cost track end pct 2-0 右鍵單擊FactInternetSales > 分區。 創建如下分區: FactInternetSales2010。SQL: SELECT [dbo].[FactInterne

深度學習系列用PaddlePaddle和Tensorflow實現經典CNN網絡GoogLeNet

mage eat oba card fin filter mod 一個 lec   前面講了LeNet、AlexNet和Vgg,這周來講講GoogLeNet。GoogLeNet是由google的Christian Szegedy等人在2014年的論文《Going Deepe

深度學習系列用PaddlePaddle和Tensorflow實現GoogLeNet InceptionV2/V3/V4

targe 所有 conn ride 出了 prev 縮減 tro 例如   上一篇文章我們引出了GoogLeNet InceptionV1的網絡結構,這篇文章中我們會詳細講到Inception V2/V3/V4的發展歷程以及它們的網絡結構和亮點。 GoogLeNet I

ASP.NET系列詳解Views

rbo mode 轉義 顯示 ora style i++ 直觀 pre 描述 本片文章內容屬於ASP.NET MVC系列視圖篇,主要講解View,大致內容如下: 1.Views文件夾講解 2.View種類 3.Razor語法 4.對視圖的基本操作 一

深度學習系列一起來參加百度 PaddlePaddle AI 大賽吧!

人工 領域 而且 標註數據 sea nload 類型 指定路徑 ear   寫這個系列寫了兩個月了,對paddlepaddle的使用越來越熟悉,不過一直沒找到合適的應用場景。最近百度搞了個AI大賽,據說有四個賽題,現在是第一個----綜藝節目精彩片段預測 ,大家可以去檢測一