快速掌握訊息佇列MQ最核心,圖文並茂詳解

語言: CN / TW / HK

訊息佇列MQ是大型分散式系統不可缺少的中介軟體,也是高併發系統的基石中介軟體,其重要性不言而喻。

本篇通過圖文並茂的方式,對訊息佇列MQ來完整詳解,助你快速掌握訊息佇列 MQ 最核心的東西,譬如:訊息佇列MQ的主流應用場景、主流產品與選型、以及設計一個訊息佇列MQ該如何下手等。

建議收藏備用!

——不囉嗦了,下面進入正文!嘀嘀!準備上車了!!——

史上最強訊息佇列MQ萬字圖文總結!-mikechen的網際網路架構

 

訊息佇列MQ概述

訊息佇列(Message Queue,簡稱MQ),指儲存訊息的一個容器,本質是個佇列。

訊息(Message)是指在應用之間傳送的資料,訊息可以非常簡單,比如只包含文字字串,也可以更復雜,可能包含嵌入物件。

下圖便是訊息佇列的基本模型,向訊息佇列中存放資料的叫做生產者,從訊息佇列中獲取資料的叫做消費者。

 
 
 

訊息佇列MQ應用場景

 

1.非同步處理

訊息佇列的主要特點是非同步處理,主要目的是減少請求響應時間,實現非核心流程非同步化,提高系統響應效能。

舉一個使用者註冊的例子,使用者註冊成功後,系統需要傳送注簡訊註冊成功通知,以及贈送註冊成功的積分。

1)同步

 

同步的總耗時:10ms+100ms+100ms=210ms

由於簡訊通知與增加積分為非核心流程,為了提升系統響應效能,從而我把它改造為非同步。

 

2)非同步

 

改造後就變成上圖,之前需要等使用者註冊10ms+簡訊通知100ms+增加積分100ms才能返回,現在把簡訊通知和增加積分改為非同步的形式,使用者註冊後寫入訊息10ms左右立即返回成功給客戶端,無需等待耗時較久的同步(簡訊+積分)就可以返回,從而極大地提升了系統的吞吐量。

所以非同步的典型場景就是將比較耗時而且不需要即時(同步)返回結果的操作,通過訊息佇列來實現非同步化。

 

2.應用解耦

使用了訊息佇列後,只要保證訊息格式不變,訊息的傳送方和接收方並不需要彼此聯絡,也不需要受對方的影響,即解耦。

每個成員不必受其他成員影響,可以更獨立自主,只通過訊息佇列MQ來聯絡,典型的上下游解耦如下圖所示: 

 

3.流量削鋒

流量削鋒也是訊息佇列中的常用場景,一般在秒殺或團搶活動中使用廣泛。

這種場景中系統的峰值流量往往集中於一小段時間內,所以為了防止系統在短時間內的峰值流量沖垮,往往採用訊息佇列來削弱峰值流量,相當於訊息佇列做了一次緩衝。 

 
  

4. 日誌處理

日誌處理是指將訊息佇列用在日誌處理中,比如Kafka的應用,解決大量日誌傳輸的問題。

 

 

訊息佇列MQ設計

1. 整體架構

 
 

上圖為整體架構,會涉及三類角色:

1)Producer 訊息生產者:負責產生和傳送訊息到 Broker;

2)Broker 訊息處理中心:負責訊息儲存、確認、重試等,一般其中會包含多個 queue;

3)Consumer 訊息消費者:負責從 Broker 中獲取訊息,並進行相應處理;

 

2. 詳細設計

 
 

詳細的流程如上圖,producer傳送給broker,broker傳送給consumer,consumer回覆消費確認,broker刪除/備份訊息等。

 

1)RPC 通訊

圖上的第一個步驟:Producer生產訊息向Broker傳送會涉及通訊的問題,同樣Consumer 消費訊息也會涉及通訊的問題。

上圖中的Producer,Broker,Consumer最後就通過RPC將資料流串起來了,所以需要解決通訊的問題。

你可以基於Netty 來做底層通訊,用 Zookeeper、Euraka 等來做註冊中心,然後自定義一套新的通訊協議。

也可以直接利用成熟的 RPC 框架 Dubbo 或者 Thrift 實現即可,這樣不需要考慮服務註冊與發現、負載均衡、通訊協議、序列化方式等一系列問題了。

 

2)Broker儲存

圖上第二個步驟,訊息到達服務端後需要儲存到Broker。

大家關注的流量削峰、最終一致性等需求都是需要Broker先儲存下來,然後選擇時機投遞,這才達到流量削峰、洩洪的目的,所以Broker一個非常重要的功能就是儲存。

儲存可以做成很多方式,比如儲存在記憶體裡,儲存在分散式KV裡,儲存在磁盤裡,儲存在資料庫裡等等,儲存的選型需要綜合考慮效能/高可用和開發維護成本等諸多因素。

目前主流的方案:追加寫日誌檔案(資料部分) + 索引檔案的方式,索引設計上可以考慮稠密索引或者稀疏索引,查詢訊息可以利用跳轉表、二分查詢等,還可以通過作業系統的頁快取、零拷貝等技術來提升磁碟檔案的讀寫效能。

 

3)消費模型

圖上第三個步驟,訊息到達Broker後,最終還是需要Consumer去消費訊息,這裡就會涉及到消費模型。

這裡的消費模型,目前主要就兩種:單播和廣播。所謂單播,就是點到點;而廣播,是一點對多點。

詳細的單播和廣播消費模型,下面我會圖文詳解。

 

4)高階特性

圖上第四個步驟,如果Consumer端把訊息消費了,除了需要訊息確認,還會涉及比如:重複訊息、順序訊息、訊息延遲、事務訊息等需要考慮的高階特性。

 

訊息佇列MQ模型

訊息佇列MQ主要包含兩種模型:點對點與釋出訂閱兩種模型。

1.點對點模型

 
 

 

1) 角色

點對點模用於 訊息生產者 和 訊息消費者 之間 點到點 的通訊,包含三個角色:

訊息佇列(Queue)

傳送者(Sender)

接收者(Receiver)

每個訊息都被髮送到一個特定的佇列,接收者​從佇列中獲取訊息。佇列保留著訊息,可以放在 記憶體 中也可以 持久化,直到他們被消費或超時。

 

2)特點

每個訊息只有一個消費者(Consumer)(即一旦被消費,訊息就不再在訊息佇列中)

傳送者和接收者之間在時間上沒有依賴性

接收者在成功接收​訊息之後需向佇列應答成功

 

2.釋出訂閱訊息模型Topic

 
 
 

1)角色

釋出訂閱模型包含三個角色:

主題(Topic)

釋出者(Publisher)

訂閱者(Subscriber)

多個釋出者將訊息傳送到Topic,系統將這些訊息傳遞給多個訂閱者。

 

2)特點

每個訊息可以有多個消費者:和點對點方式不同,釋出訊息可以被所有訂閱者消費

釋出者和訂閱者之間有時間上的依賴性。

針對某個主題(Topic)的訂閱者,它必須建立一個訂閱者之後,才能消費釋出者的訊息。

為了消費訊息,訂閱者必須保持執行的狀態。

 

訊息佇列MQ產品選型

1.ActiveMQ

 
 

ActiveMQ官網地址:activemq.apache.org

Apache出品,最早使用的訊息佇列產品,時間比較長了,最近版本更新比較緩慢,效能在萬級/秒。

2.RabbitMQ

 
 

RabbitMQ官網地址:www.rabbitmq.com

RabbitMQ是erlang語言開發,結合erlang語言本身的併發優勢,支援很多的協議:AMQP,XMPP, SMTP, STOMP,效能在萬級/秒,其整體架構圖如下所示: 

 

3.Kafka

 

Kafka官網地址:kafka.apache.org

Kafka是由Apache軟體基金會開發的一個開源訊息系統專案,由Scala寫成。Kafka最初是由LinkedIn開發,並於2011年初開源。Kafka是一個分佈​式的、分割槽的、多複本的日誌提交服務,效能在百萬級/秒,其整體架構圖如下所示:

 

4.RocketMQ

 
 

RocketMQ官網地址:rocketmq.apache.org

阿里開源的訊息中介軟體,純Java開發,具有高吞吐量、高可用性、適合大規模分散式系統應用的特點,參考Kafka而設計的,效能在十萬級/秒,其整體架構圖如下所示:

 
 

 5.Pulsar

 

Pulsar官網地址:pulsar.apache.org

Apache Pulsar是Apache軟體基金會頂級專案,是下一代雲原生分散式訊息流平臺,集訊息、儲存、輕量化函式式計算為一體,採用計算與儲存分離架構設計,支援多租戶、持久化儲存、多機房跨區域資料複製,具有強一致性、高吞吐、低延時及高可擴充套件性等流資料儲存特性,被看作是雲原生時代實時訊息流傳輸、儲存和計算最佳解決方案,其整體架構圖如下所示:

 

6.訊息佇列選型

廣泛來說,電商、金融等對事務性要求很高的,可以考慮RocketMQ,技術挑戰不是特別高,用 RabbitMQ 是不錯的選擇,如果是大資料領域的實時計算、日誌採集等場景可以考慮 Kafka。

 

 ----end----

 

建議收藏備用,如果覺得還行,謝謝【點贊+關注】支援下。


很高興認識你,謝謝關注【mikechen的網際網路架構】,我是【陳睿mikechen】,10+年大廠架構經驗,資深架構師 CTO,曾任職阿里巴巴、淘寶、百度、攜程,專注分享:大廠架構+大廠面經+ 技術管理

 

mikechen的網際網路架構】往期文章推薦:

高併發架構系列:如何從0到1設計一個MQ訊息佇列

高併發架構系列:詳解分散式之訊息佇列的特點、選型及應用場景

高併發架構系列:Redis快取和MySQL資料一致性方案詳解

最全阿里技術P系列解讀:P5-P8的技能要求和薪資結構