一、訊息佇列(MQ)基本概念
1、什麼是 MQ ?
MQ:message queen,訊息佇列(先進先出的資料結構)
先進先出
2、應用場景
① 應用解耦
系統的耦合性越高,容錯率越低。比如一個訂單系統,包含支付系統,庫存系統,物流系統,如果耦合呼叫,任何一個子系統出現故障或者升級等原因不可用,會造成下單異常,影響使用者體驗。
未使用 MQ
使用 MQ
② 流量削峰
比如“秒殺活動”,系統請求流量瞬間猛增,訊息佇列可以把大量請求快取起來,分散到很長時間去處理,從而提高系統穩定性和使用者體驗。
未使用 MQ
使用 MQ
③ 資料分發
未使用 MQ
需求總是在不斷變化,比如 A 系統 需要向 B,C,D,E 分發資料,如果 D, E系統有調整,需要修改 A 系統程式碼。
使用 MQ
3、MQ 的優缺點
① 優點
解耦、削峰、資料分發
② 缺點
I、系統可用性降低
系統引入的外部依賴越多,系統穩定性越差。如果 MQ 宕機,業務會影響。
II、系統複雜度提高
MQ 增加了系統的複雜度,未使用前是同步遠端呼叫,使用後非同步呼叫。
III、一致性問題
A 系統處理完業務,透過 MQ 分發 B、C、D、E,如何保證 B、C、D、E之間的一致性問題
4、各種 MQ 產品比較
二、RocketMQ
RocketMQ 是阿里 2016 年 MQ 中介軟體,使用 Java 語言開發
1、RocketMQ 環境
2020 最新版本是 4.7.1
2、啟動 RocketMQ
① 啟動 NameServer
② 啟動 Broker
3、RocketMQ 叢集角色
官方文件:http://jm.taobao.org/2017/01/12/rocketmq-quick-start-in-10-minutes/
四個組成部分:
① Name Server:管理 Broker,類似服務員;
Name Server 是一個幾乎無狀態節點,可叢集部署,節點之間無任何資訊同步。
② Broker:暫存和傳輸資訊,類似選單;
Broker 部署相對複雜,Broker 分為 Master 與 Slave,一個 Master 可以對應多個 Slave,但是一個 Slave 只能對應一個 Master,Master 與 Slave 的對應關係透過指定相同的 BrokerName,不同的 BrokerId 來定義,BrokerId 為 0 表示 Master,非 0 表示 Slave。Master 也可以部署多個。每個 Broker 與 Name Server 叢集中的所有節點建立長連線,定時註冊 Topic 資訊到所有 Name Server。
③ Producer 叢集:訊息的傳送者,類似廚師;
Producer 與 Name Server 叢集中的其中一個節點(隨機選擇)建立長連線,定期從 Name Server 取 Topic 路由資訊,並向提供 Topic 服務的 Master 建立長連線,且定時向 Master 傳送心跳。Producer 完全無狀態,可叢集部署。
④ Consumer 叢集:訊息的接受者,類似顧客;
Consumer 與 Name Server 叢集中的其中一個節點(隨機選擇)建立長連線,定期從 Name Server 取 Topic 路由資訊,並向提供 Topic 服務的 Master、Slave 建立長連線,且定時向 Master、Slave 傳送心跳。Consumer 既可以從 Master 訂閱訊息,也可以從 Slave 訂閱訊息,訂閱規則由 Broker 配置決定。
⑤ Topic :區分訊息的種類
一個傳送者可以發訊息給 1-N 個 Topic,一個訊息的接受者可以訂閱 1-N 個 Topic 訊息
⑥ Message Queue :相當於 Topic 的子類別,用於並行傳送和接收訊息
4、RocketMQ 叢集架構(2m-2s同步雙寫)
工作流程:
① 啟動 NameServer,NameServer 啟動成功監聽埠,等待 Broker、Producer、Consumer 連線,相當於路由中心;
② Broker 啟動,跟所有 NameServer 保持長連線,定時傳送心跳包(包含 Broker 資訊以及儲存的所有 Topic 資訊)。註冊成功後,NameServer 叢集就有 Topic 跟 Broker 的對映關係;
③ 收發訊息前,先建立 Topic,建立 Topic 時需要指定該 Topic 儲存在那些 Broker 上,也可以在傳送訊息時自動建立(啟動 broker 需要加上 autoCreateTopicEnable=true );
④ Producer 傳送訊息,啟動時先跟 NameServer 叢集中的一臺建立長連線,並從 NameServer 中獲取當前傳送的 Topic 存在哪些 Broker 上,輪詢從佇列列表中選擇一個佇列,然後與佇列所在的 Broker 建立長連線,從而向 Broker 發訊息;
⑤ Consumer 跟 Producer 類似,跟其中一臺 NameServer 建立長連線,獲取當前訂閱 Topic 存在哪些 Broker 中,然後直接跟 Broker 建立通道,開始消費訊息。
5、RocketMQ 視覺化介面
Github 專案地址:https://github.com/apache/rocketmq-externals
application.properties 修改成自己的配置
執行編譯後的 jar 包 :java -jar 包名
6、Java RocketMQ 使用
① Maven 依賴
② 生產者傳送訊息步驟
建立 Producer,並制定生產者組名
制定 NameServer 地址
啟動 Producer
建立訊息物件,指定主題 Topic 、Tag 和 訊息體
傳送訊息
關閉 Producer
③ 消費者消費訊息步驟
建立 Consumer,並制定消費者組名
制定 NameServer 地址
訂閱主題 Topic 和 Tag
設定回撥函式,處理訊息
啟動 Consumer
7、SpringBoot 整合 RocketMQ 同步傳送訊息
以下展示的是 MQ 傳送同步訊息,可靠性高,使用場景:重要訊息通知,簡訊通知
provider 專案
I. application.properties
II、RocketMQ MQProducerConfiguration 配置類
III、傳送訊息
列印日誌:
8、SpringBoot 整合 RocketMQ 非同步傳送訊息
非同步訊息通常用在對響應時間敏感的業務場景,即傳送端不能容忍長時間等待 Broker 的響應,可靠性比同步低。
9、傳送單向訊息
這種方式主要用在不特別關心傳送結果的場景,例如日誌傳送
10、SpringBoot 整合 RocketMQ 同步接受訊息
Consumer
I. application.properties
II、RocketMQ MQConsumerConfiguration 配置類
注意:訊息類有 2 種,一是 BROADCASTING(廣播模式),二是 CLUSTERING(預設是叢集模式)
當 Consumer 使用叢集模式時,每條訊息只會被 Consumer 叢集內的任意一個 Consumer 例項消費一次。
當 Consumer 使用廣播模式時,每條訊息都會被 Consumer 叢集內所有的 Consumer 例項消費一次。
III、消費訊息
列印日誌:
歡迎關注 @Python 大星 ,一個會點 Python 的 Java 程式設計師。如果你有更好的想法,歡迎留言,一起探討,想說你就說啊!後面繼續分享 Java 的相關開發,人少就散了吧!@Python 大星
@Python 大星 | 文