天天看點

RocketMQ(前傳)——消息隊列一、何為MQ?二、MQ概述三、MQ工作原理四、MQ的通訊模式五、MQ的優點六、MQ的使用場景

提到RocketMQ,不知道親愛的程式猿們會想到什麼?哈哈,我想到的是Rocket和MQ!何為Rocket?

RocketMQ(前傳)——消息隊列一、何為MQ?二、MQ概述三、MQ工作原理四、MQ的通訊模式五、MQ的優點六、MQ的使用場景

沒錯,就是火箭,是不是感覺快得嗖嗖的。在無數剁手黨的大力配合下,經過雙11的證明,RocketMQ确實保證了系統嗖嗖的。(你懂得!)

一、何為MQ?

MQ全稱為Message Queue, 消息隊列(MQ)是一種應用程式對應用程式的通信方法。應用程式通過讀寫出入隊列的消息(針對應用程式的資料)來通信,而無需專用連接配接來連結它們。消息傳遞指的是程式之間通過在消息中發送資料進行通信,而不是通過直接調用彼此來通信,直接調用通常是用于諸如遠端過程調用的技術。排隊指的是應用程式通過 隊列來通信。隊列的使用除去了接收和發送應用程式同時執行的要求。——百度百科

差不多能看懂,簡單來說,就跟人們排隊買票是一樣,隻不過排隊的不是人,而是消息。

二、MQ概述

要讓消息隊列能有機動起來,那麼一個完整的體系包括什麼呢?首先是消息,然後是存放消息的隊列,接着就是管理隊列的管理器,以及管理器之間通信的信道:

1. 消息

在MQ中,我們把應用程式交由MQ傳輸的資料定義為消息,我們可以定義消息的内容并對消息進行廣義的了解,比如:使用者的各種類型的資料檔案,某個應用向其它應用發出的處理請求等都可以作為消息。消息有兩部分組成:

  • 消息描述符(Message Discription或Message Header),描述消息的特征,如:消息的優先級、生命周期、消息Id等;
  • 消息體(Message Body),即使用者資料部分。

在MQ中,消息分為兩種類型:

  • 非永久性(non-persistent)消息
  • 永久性(persistent)消息

非永久性消息是存儲在記憶體中的,它是為了提高性能而設計的,當系統掉電或MQ隊列管理器重新啟動時,将不可恢複。當使用者對消息的可靠性要求不高,而側重系統的性能表現時,可以采用該種類型的消息,如:當釋出股票資訊時,由于股票資訊是不斷更新的,我們可能每若幹秒就會釋出一次,新的消息會不斷覆寫舊的消息。永久性消息是存儲在硬碟上,并且紀錄資料日志的,它具有高可靠性,在網絡和系統發生故障等情況下都能確定消息不丢、不重。

此外,在MQ中,還有邏輯消息和實體消息的概念。利用邏輯消息和實體消息,我們可以将大消息進行分段處理,也可以将若幹個本身完整的消息在應用邏輯上歸為一組進行處理。

2. 隊列

隊列是消息的安全存放地,隊列存儲消息直到它被應用程式處理。消息隊列以下述方式工作:

  • 程式A形成對消息隊列系統的調用,此調用告知消息隊列系統,消息準備好了投向程式B;
  • 消息隊列系統發送此消息到程式B駐留處的系統,并将它放到程式B的隊列中;
  • 适當時間後,程式B從它的隊列中讀此消息,并處理此資訊。

由于采用了先進的程式設計思想以及内部工作機制,MQ能夠在各種網絡條件下保證消息的可靠傳遞,可以克服網絡線路品質差或不穩定的現狀,在傳輸過程中,如果通信線路出現故障或遠端的主機發生故障,本地的應用程式都不會受到影響,可以繼續發送資料,而無需等待網絡故障恢複或遠端主機正常後再重新運作。

在MQ中,隊列分為很多種類型,其中包括:

  • 本地隊列
  • 遠端隊列
  • 模闆隊列
  • 動态隊列
  • 别名隊列
  • …………

本地隊列又分為普通本地隊列和傳輸隊列,普通本地隊列是應用程式通過API對其進行讀寫操作的隊列;傳輸隊列可以了解為存儲-轉發隊列,比如:我們将某個消息交給MQ系統發送到遠端主機,而此時網絡發生故障,MQ将把消息放在傳輸隊列中暫存,當網絡恢複時,再發往遠端目的地。

遠端隊列是目的隊列在本地的定義,它類似一個位址指針,指向遠端主機上的某個目的隊列,它僅僅是個定義,不真正占用磁盤存儲空間。

模闆隊列和動态隊列是MQ的一個特色,它的一個典型用途是用作系統的可擴充性考慮。我們可以建立一個模闆隊列,當今後需要新增隊列時,每打開一個模闆隊列,MQ便會自動生成一個動态隊列,我們還可以指定該動态隊列為臨時隊列或者是永久隊列,若為臨時隊列我們可以在關閉它的同時将它删除,相反,若為永久隊列,我們可以将它永久保留,為我所用。

3. 隊列管理器

隊列管理器是MQ系統中最上層的一個概念,由它為我們提供基于隊列的消息服務。

4. 通道

通道是MQ系統中隊列管理器之間傳遞消息的管道,它是建立在實體的網絡連接配接之上的一個邏輯概念,也是MQ産品的精華。在MQ中,主要有三大類通道類型:

  • 消息通道
  • MQI通道
  • Cluster通道

消息通道是用于在MQ的伺服器和伺服器之間傳輸消息的,需要強調指出的是,該通道是單向的,它又有發送(sender), 接收(receive), 請求者(requestor), 服務者(server)等不同類型,供使用者在不同情況下使用。MQI通道是MQ Client和MQ Server之間通訊和傳輸消息用的,與消息通道不同,它的傳輸是雙向的。群集(Cluster)通道是位于同一個MQ 群集内部的隊列管理器之間通訊使用的。

三、MQ工作原理

RocketMQ(前傳)——消息隊列一、何為MQ?二、MQ概述三、MQ工作原理四、MQ的通訊模式五、MQ的優點六、MQ的使用場景

首先來看本地通訊的情況,應用程式A和應用程式B運作于同一系統A,它們之間可以借助消息隊列技術進行彼此的通訊:應用程式A向隊列1發送一條資訊,而當應用程式B需要時就可以得到該資訊。

其次是遠端通訊的情況,如果資訊傳輸的目标改為在系統B上的應用程式C,這種變化不會對應用程式A産生影響,應用程式A向隊列2發送一條資訊,系統A的MQ發現Q2所指向的目的隊列實際上位于系統B,它将資訊放到本地的一個特殊隊列——傳輸隊列(Transmission Queue)。我們建立一條從系統A到系統B的消息通道,消息通道代理将從傳輸隊列中讀取消息,并傳遞這條資訊到系統B,然後等待确認。隻有MQ接到系統B成功收到資訊的确認之後,它才從傳輸隊列中真正将該資訊删除。如果通訊線路不通,或系統B不在運作,資訊會留在傳輸隊列中,直到被成功地傳送到目的地。這是MQ最基本而最重要的技術–確定資訊傳輸,并且是一次且僅一次(once-and-only-once)的傳遞。

MQ提供了用于應用內建的松耦合的連接配接方法,因為共享資訊的應用不需要知道彼此實體位置(網絡位址);不需要知道彼此間怎樣建立通信;不需要同時處于運作狀态;不需要在同樣的作業系統或網絡環境下運作。

四、MQ的通訊模式

MQ有四種通訊模式:

1. 點對點通訊

點對點方式是最為傳統和常見的通訊方式,它支援一對一、一對多、多對多、多對一等多種配置方式,支援樹狀、網狀等多種拓撲結構。

2. 多點廣播

MQ适用于不同類型的應用。其中重要的,也是正在發展中的是”多點廣播”應用,即能夠将消息發送到多個目标站點(Destination List)。可以使用一條MQ指令将單一消息發送到多個目标站點,并確定為每一站點可靠地提供資訊。MQ不僅提供了多點廣播的功能,而且還擁有智能消息分發功能,在将一條消息發送到同一系統上的多個使用者時,MQ将消息的一個複制版本和該系統上接收者的名單發送到目标MQ系統。目标MQ系統在本地複制這些消息,并将它們發送到名單上的隊列,進而盡可能減少網絡的傳輸量。

3.釋出/訂閱(Publish/Subscribe)模式

釋出/訂閱功能使消息的分發可以突破目的隊列地理指向的限制,使消息按照特定的主題甚至内容進行分發,使用者或應用程式可以根據主題或内容接收到所需要的消息。釋出/訂閱功能使得發送者和接收者之間的耦合關系變得更為松散,發送者不必關心接收者的目的位址,而接收者也不必關心消息的發送位址,而隻是根據消息的主題進行消息的收發。在MQ家族産品中,MQ Event Broker是專門用于使用釋出/訂閱技術進行資料通訊的産品,它支援基于隊列和直接基于TCP/IP兩種方式的釋出和訂閱。

4.群集(Cluster)

為了簡化點對點通訊模式中的系統配置,MQ提供Cluster(群集)的解決方案。群集類似于一個域(Domain),群集内部的隊列管理器之間通訊時,不需要兩兩之間建立消息通道,而是采用群集(Cluster)通道與其它成員通訊,進而大大簡化了系統配置。此外,群集中的隊列管理器之間能夠自動進行負載均衡,當某一隊列管理器出現故障時,其它隊列管理器可以接管它的工作,進而大大提高系統的高可靠性。

PS:在JMS标準中,有兩種消息模型P2P(Point to Point),Publish/Subscribe(Pub/Sub)

RocketMQ 屬于DIY産品,并不遵循任何規範,但是參考了各種規範不同類産品的設計思想,隻有Publish/Subscribe(Pub/Sub)模式。

五、MQ的優點

過去幾年中,我們一直在使用、建構和宣傳消息隊列,我們認為它們是很令人敬畏的,這也不是什麼秘密。我們相信對任何架構或應用來說,消息隊列都是一個至關重要的元件,下面是十個理由:

1. 解耦

在項目啟動之初來預測将來項目會碰到什麼需求,是極其困難的。消息隊列在處理過程中間插入了一個隐含的、基于資料的接口層,兩邊的處理過程都要實作這一接口。這允許你獨立的擴充或修改兩邊的處理過程,隻要確定它們遵守同樣的接口限制。

2. 備援

有時在處理資料的時候處理過程會失敗。除非資料被持久化,否則将永遠丢失。消息隊列把資料進行持久化直到它們已經被完全處理,通過這一方式規避了資料丢失風險。在被許多消息隊列所采用的”插入-擷取-删除”範式中,在把一個消息從隊列中删除之前,需要你的處理過程明确的指出該消息已經被處理完畢,確定你的資料被安全的儲存直到你使用完畢。

3. 擴充性

因為消息隊列解耦了你的處理過程,是以增大消息入隊和處理的頻率是很容易的;隻要另外增加處理過程即可。不需要改變代碼、不需要調節參數。擴充就像調大電力按鈕一樣簡單。

4. 靈活性 & 峰值處理能力

當你的應用上了Hacker News的首頁,你将發現通路流量攀升到一個不同尋常的水準。在通路量劇增的情況下,你的應用仍然需要繼續發揮作用,但是這樣的突發流量并不常見;如果為以能處理這類峰值通路為标準來投入資源随時待命無疑是巨大的浪費。使用消息隊列能夠使關鍵元件頂住增長的通路壓力,而不是因為超出負荷的請求而完全崩潰。請檢視我們關于峰值處理能力的部落格文章了解更多此方面的資訊。

5. 可恢複性

當體系的一部分元件失效,不會影響到整個系統。消息隊列降低了程序間的耦合度,是以即使一個處理消息的程序挂掉,加入隊列中的消息仍然可以在系統恢複後被處理。而這種允許重試或者延後處理請求的能力通常是造就一個略感不便的使用者和一個沮喪透頂的使用者之間的差別。

6. 送達保證

消息隊列提供的備援機制保證了消息能被實際的處理,隻要一個程序讀取了該隊列即可。在此基礎上,IronMQ提供了一個”隻送達一次”保證。無論有多少程序在從隊列中領取資料,每一個消息隻能被處理一次。這之是以成為可能,是因為擷取一個消息隻是”預定”了這個消息,暫時把它移出了隊列。除非用戶端明确的表示已經處理完了這個消息,否則這個消息會被放回隊列中去,在一段可配置的時間之後可再次被處理。

7.排序保證

在許多情況下,資料處理的順序都很重要。消息隊列本來就是排序的,并且能保證資料會按照特定的順序來處理。

8.緩沖

在任何重要的系統中,都會有需要不同的處理時間的元素。例如,加載一張圖檔比應用過濾器花費更少的時間。消息隊列通過一個緩沖層來幫助任務最高效率的執行–寫入隊列的處理會盡可能的快速,而不受從隊列讀的預備處理的限制。該緩沖有助于控制和優化資料流經過系統的速度。

9. 了解資料流

在一個分布式系統裡,要得到一個關于使用者操作會用多長時間及其原因的總體印象,是個巨大的挑戰。消息系列通過消息被處理的頻率,來友善的輔助确定那些表現不佳的處理過程或領域,這些地方的資料流都不夠優化。

10. 異步通信

很多時候,你不想也不需要立即處理消息。消息隊列提供了異步處理機制,允許你把一個消息放入隊列,但并不立即處理它。你想向隊列中放入多少消息就放多少,然後在你樂意的時候再去處理它們。

以上内容的原文來自于《Top 10 Uses For A Message Queue》

六、MQ的使用場景

光說不練嘴把式,到底MQ能做些什麼?以下介紹消息隊列在實際應用中常用的使用場景。異步處理,應用解耦,流量削鋒和消息通訊四個場景。

1. 異步處理

場景說明:使用者注冊後,需要發注冊郵件和注冊短信。傳統的做法有

串行的方式

并行方式

兩種。

1) 串行方式

将注冊資訊寫入資料庫成功後,發送注冊郵件,再發送注冊短信。以上三個任務全部完成後,傳回給用戶端。

RocketMQ(前傳)——消息隊列一、何為MQ?二、MQ概述三、MQ工作原理四、MQ的通訊模式五、MQ的優點六、MQ的使用場景

2)并行方式

将注冊資訊寫入資料庫成功後,發送注冊郵件的同時,發送注冊短信。以上三個任務完成後,傳回給用戶端。與串行的差别是,并行的方式可以提高處理的時間。

RocketMQ(前傳)——消息隊列一、何為MQ?二、MQ概述三、MQ工作原理四、MQ的通訊模式五、MQ的優點六、MQ的使用場景

假設三個業務節點每個使用50毫秒鐘,不考慮網絡等其他開銷,則串行方式的時間是150毫秒,并行的時間可能是100毫秒。因為CPU在機關時間内處理的請求數是一定的,假設CPU1秒内吞吐量是100次。則串行方式1秒内CPU可處理的請求量是7次(1000/150)。并行方式處理的請求量是10次(1000/100)。

小結:如以上案例描述,傳統的方式系統的性能(并發量,吞吐量,響應時間)會有瓶頸。如何解決這個問題呢?

引入消息隊列,将不是必須的業務邏輯,異步處理。改造後的架構如下:

RocketMQ(前傳)——消息隊列一、何為MQ?二、MQ概述三、MQ工作原理四、MQ的通訊模式五、MQ的優點六、MQ的使用場景

按照以上約定,使用者的響應時間相當于是注冊資訊寫入資料庫的時間,也就是50毫秒。注冊郵件,發送短信寫入消息隊列後,直接傳回,是以寫入消息隊列的速度很快,基本可以忽略,是以使用者的響應時間可能是50毫秒。是以架構改變後,系統的吞吐量提高到每秒20 QPS。比串行提高了3倍,比并行提高了兩倍。

2. 應用解耦

場景說明:使用者下單後,訂單系統需要通知庫存系統。傳統的做法是,訂單系統調用庫存系統的接口。如下圖:

RocketMQ(前傳)——消息隊列一、何為MQ?二、MQ概述三、MQ工作原理四、MQ的通訊模式五、MQ的優點六、MQ的使用場景

傳統模式的缺點:

  • 假如庫存系統無法通路,則訂單減庫存将失敗,進而導緻訂單失敗;
  • 訂單系統與庫存系統耦合。

如何解決以上問題呢?引入應用消息隊列後的方案,如下圖:

RocketMQ(前傳)——消息隊列一、何為MQ?二、MQ概述三、MQ工作原理四、MQ的通訊模式五、MQ的優點六、MQ的使用場景

訂單系統:使用者下單後,訂單系統完成持久化處理,将消息寫入消息隊列,傳回使用者訂單下單成功。

庫存系統:訂閱下單的消息,采用拉/推的方式,擷取下單資訊,庫存系統根據下單資訊,進行庫存操作。

假如,在下單時庫存系統不能正常使用。也不影響正常下單,因為下單後,訂單系統寫入消息隊列就不再關心其他的後續操作了。實作訂單系統與庫存系統的應用解耦。

3. 流量削鋒

流量削鋒也是消息隊列中的常用場景,一般在秒殺或團搶活動中使用廣泛。如,秒殺活動中,一般會因為流量過大,導緻流量暴增,應用挂掉。為解決這個問題,一般需要在應用前端加入消息隊列。這樣以來可以控制活動的人數,可以緩解短時間内高流量壓垮應用。

RocketMQ(前傳)——消息隊列一、何為MQ?二、MQ概述三、MQ工作原理四、MQ的通訊模式五、MQ的優點六、MQ的使用場景

使用者的請求,伺服器接收後,首先寫入消息隊列。假如消息隊列長度超過最大數量,則直接抛棄使用者請求或跳轉到錯誤頁面;秒殺業務根據消息隊列中的請求資訊,再做後續處理。

4. 日志處理

日志處理是指将消息隊列用在日志進行中,比如Kafka的應用,解決大量日志傳輸的問題。架構簡化如下:

RocketMQ(前傳)——消息隊列一、何為MQ?二、MQ概述三、MQ工作原理四、MQ的通訊模式五、MQ的優點六、MQ的使用場景

日志采集用戶端,負責日志資料采集,定時寫受寫入Kafka隊列;

Kafka消息隊列,負責日志資料的接收,存儲和轉發;

日志處理應用:訂閱并消費kafka隊列中的日志資料;

以下是新浪kafka日志處理應用案例:《新浪技術分享:我們如何扛下32億條實時日志的分析處理》

RocketMQ(前傳)——消息隊列一、何為MQ?二、MQ概述三、MQ工作原理四、MQ的通訊模式五、MQ的優點六、MQ的使用場景

Kafka:接收使用者日志的消息隊列。

Logstash:做日志解析,統一成JSON輸出給Elasticsearch。

Elasticsearch:實時日志分析服務的核心技術,一個schemaless,實時的資料存儲服務,通過index組織資料,兼具強大的搜尋和統計功能。

Kibana:基于Elasticsearch的資料可視化元件,超強的資料可視化能力是衆多公司選擇ELK stack的重要原因。

5. 消息通訊

消息通訊是指,消息隊列一般都内置了高效的通信機制,是以也可以用在純的消息通訊。比如實作點對點消息隊列,或者聊天室等。

點對點通訊:

RocketMQ(前傳)——消息隊列一、何為MQ?二、MQ概述三、MQ工作原理四、MQ的通訊模式五、MQ的優點六、MQ的使用場景

用戶端A和用戶端B使用同一隊列,進行消息通訊。

聊天室通訊:

RocketMQ(前傳)——消息隊列一、何為MQ?二、MQ概述三、MQ工作原理四、MQ的通訊模式五、MQ的優點六、MQ的使用場景

用戶端A,用戶端B,用戶端N訂閱同一主題,進行消息釋出和接收。實作類似聊天室效果。

以上實際是消息隊列的兩種消息模式,點對點或釋出訂閱模式。模型為示意圖,供參考。

内容比較多哈,在此聲明一下,以上内容多來自于網絡中,做為總結、學習而用!

繼續閱讀