MQ(Message Queue)简介
一、何為MQ?
| MQ全稱為Message Queue, 消息隊列(MQ)是一種應(yīng)用程序?qū)?yīng)用程序的通信方法。應(yīng)用程序通過讀寫出入隊列的消息(針對應(yīng)用程序的數(shù)據(jù))來通信,而無需專用連接來鏈接它們。消息傳遞指的是程序之間通過在消息中發(fā)送數(shù)據(jù)進行通信,而不是通過直接調(diào)用彼此來通信,直接調(diào)用通常是用于諸如遠程過程調(diào)用的技術(shù)。排隊指的是應(yīng)用程序通過隊列來通信。隊列的使用除去了接收和發(fā)送應(yīng)用程序同時執(zhí)行的要求。——百度百科 |
差不多能看懂,簡單來說,就跟人們排隊買票是一樣,只不過排隊的不是人,而是消息。
二、MQ概述
要讓消息隊列能有機動起來,那么一個完整的體系包括什么呢?首先是消息,然后是存放消息的隊列,接著就是管理隊列的管理器,以及管理器之間通信的信道:
1. 消息
在MQ中,我們把應(yīng)用程序交由MQ傳輸?shù)臄?shù)據(jù)定義為消息,我們可以定義消息的內(nèi)容并對消息進行廣義的理解,比如:用戶的各種類型的數(shù)據(jù)文件,某個應(yīng)用向其它應(yīng)用發(fā)出的處理請求等都可以作為消息。消息有兩部分組成:
- 消息描述符(Message Discription或Message Header),描述消息的特征,如:消息的優(yōu)先級、生命周期、消息Id等;
- 消息體(Message Body),即用戶數(shù)據(jù)部分。
在MQ中,消息分為兩種類型:
- 非永久性(non-persistent)消息
- 永久性(persistent)消息
非永久性消息是存儲在內(nèi)存中的,它是為了提高性能而設(shè)計的,當系統(tǒng)掉電或MQ隊列管理器重新啟動時,將不可恢復。當用戶對消息的可靠性要求不高,而側(cè)重系統(tǒng)的性能表現(xiàn)時,可以采用該種類型的消息,如:當發(fā)布股票信息時,由于股票信息是不斷更新的,我們可能每若干秒就會發(fā)布一次,新的消息會不斷覆蓋舊的消息。永久性消息是存儲在硬盤上,并且紀錄數(shù)據(jù)日志的,它具有高可靠性,在網(wǎng)絡(luò)和系統(tǒng)發(fā)生故障等情況下都能確保消息不丟、不重。
此外,在MQ中,還有邏輯消息和物理消息的概念。利用邏輯消息和物理消息,我們可以將大消息進行分段處理,也可以將若干個本身完整的消息在應(yīng)用邏輯上歸為一組進行處理。
2. 隊列
隊列是消息的安全存放地,隊列存儲消息直到它被應(yīng)用程序處理。消息隊列以下述方式工作:
- 程序A形成對消息隊列系統(tǒng)的調(diào)用,此調(diào)用告知消息隊列系統(tǒng),消息準備好了投向程序B;
- 消息隊列系統(tǒng)發(fā)送此消息到程序B駐留處的系統(tǒng),并將它放到程序B的隊列中;
- 適當時間后,程序B從它的隊列中讀此消息,并處理此信息。
由于采用了先進的程序設(shè)計思想以及內(nèi)部工作機制,MQ能夠在各種網(wǎng)絡(luò)條件下保證消息的可靠傳遞,可以克服網(wǎng)絡(luò)線路質(zhì)量差或不穩(wěn)定的現(xiàn)狀,在傳輸過程中,如果通信線路出現(xiàn)故障或遠端的主機發(fā)生故障,本地的應(yīng)用程序都不會受到影響,可以繼續(xù)發(fā)送數(shù)據(jù),而無需等待網(wǎng)絡(luò)故障恢復或遠端主機正常后再重新運行。
在MQ中,隊列分為很多種類型,其中包括:
- 本地隊列
- 遠程隊列
- 模板隊列
- 動態(tài)隊列
- 別名隊列
- …………
本地隊列又分為普通本地隊列和傳輸隊列,普通本地隊列是應(yīng)用程序通過API對其進行讀寫操作的隊列;傳輸隊列可以理解為存儲-轉(zhuǎn)發(fā)隊列,比如:我們將某個消息交給MQ系統(tǒng)發(fā)送到遠程主機,而此時網(wǎng)絡(luò)發(fā)生故障,MQ將把消息放在傳輸隊列中暫存,當網(wǎng)絡(luò)恢復時,再發(fā)往遠端目的地。
遠程隊列是目的隊列在本地的定義,它類似一個地址指針,指向遠程主機上的某個目的隊列,它僅僅是個定義,不真正占用磁盤存儲空間。
模板隊列和動態(tài)隊列是MQ的一個特色,它的一個典型用途是用作系統(tǒng)的可擴展性考慮。我們可以創(chuàng)建一個模板隊列,當今后需要新增隊列時,每打開一個模板隊列,MQ便會自動生成一個動態(tài)隊列,我們還可以指定該動態(tài)隊列為臨時隊列或者是永久隊列,若為臨時隊列我們可以在關(guān)閉它的同時將它刪除,相反,若為永久隊列,我們可以將它永久保留,為我所用。
3. 隊列管理器
隊列管理器是MQ系統(tǒng)中最上層的一個概念,由它為我們提供基于隊列的消息服務(wù)。
4. 通道
通道是MQ系統(tǒng)中隊列管理器之間傳遞消息的管道,它是建立在物理的網(wǎng)絡(luò)連接之上的一個邏輯概念,也是MQ產(chǎn)品的精華。在MQ中,主要有三大類通道類型:
- 消息通道
- MQI通道
- Cluster通道
消息通道是用于在MQ的服務(wù)器和服務(wù)器之間傳輸消息的,需要強調(diào)指出的是,該通道是單向的,它又有發(fā)送(sender), 接收(receive), 請求者(requestor), 服務(wù)者(server)等不同類型,供用戶在不同情況下使用。MQI通道是MQ Client和MQ Server之間通訊和傳輸消息用的,與消息通道不同,它的傳輸是雙向的。群集(Cluster)通道是位于同一個MQ 群集內(nèi)部的隊列管理器之間通訊使用的。
三、MQ工作原理
?
首先來看本地通訊的情況,應(yīng)用程序A和應(yīng)用程序B運行于同一系統(tǒng)A,它們之間可以借助消息隊列技術(shù)進行彼此的通訊:應(yīng)用程序A向隊列1發(fā)送一條信息,而當應(yīng)用程序B需要時就可以得到該信息。
其次是遠程通訊的情況,如果信息傳輸?shù)哪繕烁臑樵谙到y(tǒng)B上的應(yīng)用程序C,這種變化不會對應(yīng)用程序A產(chǎn)生影響,應(yīng)用程序A向隊列2發(fā)送一條信息,系統(tǒng)A的MQ發(fā)現(xiàn)Q2所指向的目的隊列實際上位于系統(tǒng)B,它將信息放到本地的一個特殊隊列——傳輸隊列(Transmission Queue)。我們建立一條從系統(tǒng)A到系統(tǒng)B的消息通道,消息通道代理將從傳輸隊列中讀取消息,并傳遞這條信息到系統(tǒng)B,然后等待確認。只有MQ接到系統(tǒng)B成功收到信息的確認之后,它才從傳輸隊列中真正將該信息刪除。如果通訊線路不通,或系統(tǒng)B不在運行,信息會留在傳輸隊列中,直到被成功地傳送到目的地。這是MQ最基本而最重要的技術(shù)–確保信息傳輸,并且是一次且僅一次(once-and-only-once)的傳遞。
MQ提供了用于應(yīng)用集成的松耦合的連接方法,因為共享信息的應(yīng)用不需要知道彼此物理位置(網(wǎng)絡(luò)地址);不需要知道彼此間怎樣建立通信;不需要同時處于運行狀態(tài);不需要在同樣的操作系統(tǒng)或網(wǎng)絡(luò)環(huán)境下運行。
四、MQ的通訊模式
MQ有四種通訊模式:
1. 點對點通訊
點對點方式是最為傳統(tǒng)和常見的通訊方式,它支持一對一、一對多、多對多、多對一等多種配置方式,支持樹狀、網(wǎng)狀等多種拓撲結(jié)構(gòu)。
2. 多點廣播
MQ適用于不同類型的應(yīng)用。其中重要的,也是正在發(fā)展中的是”多點廣播”應(yīng)用,即能夠?qū)⑾l(fā)送到多個目標站點(Destination List)。可以使用一條MQ指令將單一消息發(fā)送到多個目標站點,并確保為每一站點可靠地提供信息。MQ不僅提供了多點廣播的功能,而且還擁有智能消息分發(fā)功能,在將一條消息發(fā)送到同一系統(tǒng)上的多個用戶時,MQ將消息的一個復制版本和該系統(tǒng)上接收者的名單發(fā)送到目標MQ系統(tǒng)。目標MQ系統(tǒng)在本地復制這些消息,并將它們發(fā)送到名單上的隊列,從而盡可能減少網(wǎng)絡(luò)的傳輸量。
3.發(fā)布/訂閱(Publish/Subscribe)模式
發(fā)布/訂閱功能使消息的分發(fā)可以突破目的隊列地理指向的限制,使消息按照特定的主題甚至內(nèi)容進行分發(fā),用戶或應(yīng)用程序可以根據(jù)主題或內(nèi)容接收到所需要的消息。
發(fā)布/訂閱功能使得發(fā)送者和接收者之間的耦合關(guān)系變得更為松散,發(fā)送者不必關(guān)心接收者的目的地址,而接收者也不必關(guān)心消息的發(fā)送地址,而只是根據(jù)消息的主題進行消息的收發(fā)。在MQ家族產(chǎn)品中,MQ Event Broker是專門用于使用發(fā)布/訂閱技術(shù)進行數(shù)據(jù)通訊的產(chǎn)品,它支持基于隊列和直接基于TCP/IP兩種方式的發(fā)布和訂閱。
4.群集(Cluster)
為了簡化點對點通訊模式中的系統(tǒng)配置,MQ提供Cluster(群集)的解決方案。群集類似于一個域(Domain),群集內(nèi)部的隊列管理器之間通訊時,不需要兩兩之間建立消息通道,而是采用群集(Cluster)通道與其它成員通訊,從而大大簡化了系統(tǒng)配置。此外,群集中的隊列管理器之間能夠自動進行負載均衡,當某一隊列管理器出現(xiàn)故障時,其它隊列管理器可以接管它的工作,從而大大提高系統(tǒng)的高可靠性。
PS:在JMS標準中,有兩種消息模型P2P(Point to Point),Publish/Subscribe(Pub/Sub)??
五、MQ的優(yōu)點
過去幾年中,我們一直在使用、構(gòu)建和宣傳消息隊列,我們認為它們是很令人敬畏的,這也不是什么秘密。我們相信對任何架構(gòu)或應(yīng)用來說,消息隊列都是一個至關(guān)重要的組件,下面是十個理由:
1. 解耦
在項目啟動之初來預測將來項目會碰到什么需求,是極其困難的。消息隊列在處理過程中間插入了一個隱含的、基于數(shù)據(jù)的接口層,兩邊的處理過程都要實現(xiàn)這一接口。這允許你獨立的擴展或修改兩邊的處理過程,只要確保它們遵守同樣的接口約束。
2. 冗余
有時在處理數(shù)據(jù)的時候處理過程會失敗。除非數(shù)據(jù)被持久化,否則將永遠丟失。消息隊列把數(shù)據(jù)進行持久化直到它們已經(jīng)被完全處理,通過這一方式規(guī)避了數(shù)據(jù)丟失風險。在被許多消息隊列所采用的”插入-獲取-刪除”范式中,在把一個消息從隊列中刪除之前,需要你的處理過程明確的指出該消息已經(jīng)被處理完畢,確保你的數(shù)據(jù)被安全的保存直到你使用完畢。
3. 擴展性
因為消息隊列解耦了你的處理過程,所以增大消息入隊和處理的頻率是很容易的;只要另外增加處理過程即可。不需要改變代碼、不需要調(diào)節(jié)參數(shù)。擴展就像調(diào)大電力按鈕一樣簡單。
4. 靈活性 & 峰值處理能力
當你的應(yīng)用上了Hacker News的首頁,你將發(fā)現(xiàn)訪問流量攀升到一個不同尋常的水平。在訪問量劇增的情況下,你的應(yīng)用仍然需要繼續(xù)發(fā)揮作用,但是這樣的突發(fā)流量并不常見;如果為以能處理這類峰值訪問為標準來投入資源隨時待命無疑是巨大的浪費。使用消息隊列能夠使關(guān)鍵組件頂住增長的訪問壓力,而不是因為超出負荷的請求而完全崩潰。請查看我們關(guān)于峰值處理能力的博客文章了解更多此方面的信息。
5. 可恢復性
當體系的一部分組件失效,不會影響到整個系統(tǒng)。消息隊列降低了進程間的耦合度,所以即使一個處理消息的進程掛掉,加入隊列中的消息仍然可以在系統(tǒng)恢復后被處理。而這種允許重試或者延后處理請求的能力通常是造就一個略感不便的用戶和一個沮喪透頂?shù)挠脩糁g的區(qū)別。
6. 送達保證
消息隊列提供的冗余機制保證了消息能被實際的處理,只要一個進程讀取了該隊列即可。在此基礎(chǔ)上,IronMQ提供了一個”只送達一次”保證。無論有多少進程在從隊列中領(lǐng)取數(shù)據(jù),每一個消息只能被處理一次。這之所以成為可能,是因為獲取一個消息只是”預定”了這個消息,暫時把它移出了隊列。除非客戶端明確的表示已經(jīng)處理完了這個消息,否則這個消息會被放回隊列中去,在一段可配置的時間之后可再次被處理。
7.排序保證
在許多情況下,數(shù)據(jù)處理的順序都很重要。消息隊列本來就是排序的,并且能保證數(shù)據(jù)會按照特定的順序來處理。
8.緩沖
在任何重要的系統(tǒng)中,都會有需要不同的處理時間的元素。例如,加載一張圖片比應(yīng)用過濾器花費更少的時間。消息隊列通過一個緩沖層來幫助任務(wù)最高效率的執(zhí)行–寫入隊列的處理會盡可能的快速,而不受從隊列讀的預備處理的約束。該緩沖有助于控制和優(yōu)化數(shù)據(jù)流經(jīng)過系統(tǒng)的速度。
9. 理解數(shù)據(jù)流
在一個分布式系統(tǒng)里,要得到一個關(guān)于用戶操作會用多長時間及其原因的總體印象,是個巨大的挑戰(zhàn)。消息系列通過消息被處理的頻率,來方便的輔助確定那些表現(xiàn)不佳的處理過程或領(lǐng)域,這些地方的數(shù)據(jù)流都不夠優(yōu)化。
10. 異步通信
很多時候,你不想也不需要立即處理消息。消息隊列提供了異步處理機制,允許你把一個消息放入隊列,但并不立即處理它。你想向隊列中放入多少消息就放多少,然后在你樂意的時候再去處理它們。
六、MQ的使用場景
光說不練嘴把式,到底MQ能做些什么?以下介紹消息隊列在實際應(yīng)用中常用的使用場景。異步處理,應(yīng)用解耦,流量削鋒和消息通訊四個場景。
1. 異步處理
場景說明:用戶注冊后,需要發(fā)注冊郵件和注冊短信。傳統(tǒng)的做法有串行的方式和并行方式兩種。
將注冊信息寫入數(shù)據(jù)庫成功后,發(fā)送注冊郵件,再發(fā)送注冊短信。以上三個任務(wù)全部完成后,返回給客戶端。?
?
將注冊信息寫入數(shù)據(jù)庫成功后,發(fā)送注冊郵件的同時,發(fā)送注冊短信。以上三個任務(wù)完成后,返回給客戶端。與串行的差別是,并行的方式可以提高處理的時間。?
?
假設(shè)三個業(yè)務(wù)節(jié)點每個使用50毫秒鐘,不考慮網(wǎng)絡(luò)等其他開銷,則串行方式的時間是150毫秒,并行的時間可能是100毫秒。因為CPU在單位時間內(nèi)處理的請求數(shù)是一定的,假設(shè)CPU1秒內(nèi)吞吐量是100次。則串行方式1秒內(nèi)CPU可處理的請求量是7次(1000/150)。并行方式處理的請求量是10次(1000/100)。
小結(jié):如以上案例描述,傳統(tǒng)的方式系統(tǒng)的性能(并發(fā)量,吞吐量,響應(yīng)時間)會有瓶頸。如何解決這個問題呢??
引入消息隊列,將不是必須的業(yè)務(wù)邏輯,異步處理。改造后的架構(gòu)如下:?
按照以上約定,用戶的響應(yīng)時間相當于是注冊信息寫入數(shù)據(jù)庫的時間,也就是50毫秒。注冊郵件,發(fā)送短信寫入消息隊列后,直接返回,因此寫入消息隊列的速度很快,基本可以忽略,因此用戶的響應(yīng)時間可能是50毫秒。因此架構(gòu)改變后,系統(tǒng)的吞吐量提高到每秒20 QPS。比串行提高了3倍,比并行提高了兩倍。
2. 應(yīng)用解耦
場景說明:用戶下單后,訂單系統(tǒng)需要通知庫存系統(tǒng)。傳統(tǒng)的做法是,訂單系統(tǒng)調(diào)用庫存系統(tǒng)的接口。如下圖:
?
?
傳統(tǒng)模式的缺點:
- 假如庫存系統(tǒng)無法訪問,則訂單減庫存將失敗,從而導致訂單失敗;
- 訂單系統(tǒng)與庫存系統(tǒng)耦合。
如何解決以上問題呢?引入應(yīng)用消息隊列后的方案,如下圖:?
訂單系統(tǒng):用戶下單后,訂單系統(tǒng)完成持久化處理,將消息寫入消息隊列,返回用戶訂單下單成功。?
庫存系統(tǒng):訂閱下單的消息,采用拉/推的方式,獲取下單信息,庫存系統(tǒng)根據(jù)下單信息,進行庫存操作。
假如,在下單時庫存系統(tǒng)不能正常使用。也不影響正常下單,因為下單后,訂單系統(tǒng)寫入消息隊列就不再關(guān)心其他的后續(xù)操作了。實現(xiàn)訂單系統(tǒng)與庫存系統(tǒng)的應(yīng)用解耦。
3. 流量削鋒
流量削鋒也是消息隊列中的常用場景,一般在秒殺或團搶活動中使用廣泛。如,秒殺活動中,一般會因為流量過大,導致流量暴增,應(yīng)用掛掉。
為解決這個問題,一般需要在應(yīng)用前端加入消息隊列。這樣以來可以控制活動的人數(shù),可以緩解短時間內(nèi)高流量壓垮應(yīng)用。
用戶的請求,服務(wù)器接收后,首先寫入消息隊列。假如消息隊列長度超過最大數(shù)量,則直接拋棄用戶請求或跳轉(zhuǎn)到錯誤頁面;秒殺業(yè)務(wù)根據(jù)消息隊列中的請求信息,再做后續(xù)處理。
4. 日志處理
日志處理是指將消息隊列用在日志處理中,比如Kafka的應(yīng)用,解決大量日志傳輸?shù)膯栴}。架構(gòu)簡化如下:?
日志采集客戶端,負責日志數(shù)據(jù)采集,定時寫受寫入Kafka隊列;?
Kafka消息隊列,負責日志數(shù)據(jù)的接收,存儲和轉(zhuǎn)發(fā);?
日志處理應(yīng)用:訂閱并消費kafka隊列中的日志數(shù)據(jù);
?
以下是新浪kafka日志處理應(yīng)用案例:《新浪技術(shù)分享:我們?nèi)绾慰赶?2億條實時日志的分析處理》?
Kafka:接收用戶日志的消息隊列。?
Logstash:做日志解析,統(tǒng)一成JSON輸出給Elasticsearch。?
Elasticsearch:實時日志分析服務(wù)的核心技術(shù),一個schemaless,實時的數(shù)據(jù)存儲服務(wù),通過index組織數(shù)據(jù),兼具強大的搜索和統(tǒng)計功能。?
Kibana:基于Elasticsearch的數(shù)據(jù)可視化組件,超強的數(shù)據(jù)可視化能力是眾多公司選擇ELK stack的重要原因。
5. 消息通訊
消息通訊是指,消息隊列一般都內(nèi)置了高效的通信機制,因此也可以用在純的消息通訊。比如實現(xiàn)點對點消息隊列,或者聊天室等。
點對點通訊:
客戶端A和客戶端B使用同一隊列,進行消息通訊。
聊天室通訊:
客戶端A,客戶端B,客戶端N訂閱同一主題,進行消息發(fā)布和接收。實現(xiàn)類似聊天室效果。
?
---------------------
作者:staybug
來源:CSDN
原文:https://blog.csdn.net/weixin_43994338/article/details/105883473
版權(quán)聲明:本文為作者原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!
內(nèi)容解析By:CSDN,CNBLOG博客文章一鍵轉(zhuǎn)載插件
總結(jié)
以上是生活随笔為你收集整理的MQ(Message Queue)简介的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 利用Python随机或暴力生成密码
- 下一篇: 39所强基计划试点高校已全部公布招生简章