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

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

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

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

  • 特色
  • 基本概念
  • 消息投遞消費的幾種姿式
  • 事務
  • 集羣

<!-- more -->node

I. 基本知識點

它是採用 Erlang 語言實現的 AMQP(Advanced Message Queued Protocol)的消息中間件,最初起源於金融系統,用在分佈式系統存儲轉發消息,目前普遍應用於各種系統用於解耦、削峯git

1.特色

首先得了解一下 rabbitmq 的特色,看看是否知足咱們的系統需求(畢竟學習一個框架也是要很多時間的)github

如下內容來自: MQ 和 RabbitMQ 做用特色

主要特色,大體能夠概括爲如下幾個spring

  • 可靠性:經過支持消息持久化,支持事務,支持消費和傳輸的 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 模式,一旦信道進入 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 能夠與綠色的 node一、node二、node3 中的任意一個利用 federation 插件進行數據同步。

IV. 其餘

0. 項目

1. 相關博文

2. 一灰灰 Blog

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

下面一灰灰的我的博客,記錄全部學習和工做中的博文,歡迎你們前去逛逛

一灰灰blog

相關文章
相關標籤/搜索