消息中間件基礎

咱們從三個方面瞭解消息中間件算法

what why how數據庫

1.  什麼是消息中間件?編程

2.  爲何要使用消息中間件?服務器

3.  怎麼用消息中間件?網絡

 

1. 什麼是消息中間件?架構

消息中間件是指一種在須要進行網絡通訊的系統進行通道的創建,數據文件發送的中間件。消息中間件的一個重要做用是能夠跨平臺操做,爲不一樣操做系統上的應用軟件集成提供便利。併發

如今愈來愈多的分佈式應用系統採用消息中間件方式來構建,人們經過使用消息中間件把應用擴展到不一樣的操做系統和不一樣的網絡環境。基於消息的機制更適用於由事件驅動的應用,當一個事件發生時,消息中間件通知服務方應該進行如何操做。負載均衡

使用消息中間件編程能夠很好地擴展到不一樣的操做系統和硬件平臺上。能夠將消息中間件的核心安裝在須要進行消息傳遞的系統上,並在它們之間創建邏輯通道,由消息中間件實現消息發送。消息中間件既能夠支持同步方式通信,又能夠支持異步方式通信,實際上它是一種點到點的機制,於是能夠很好地適用於面向對象的編程方式。異步

 

當今市面上有不少主流的消息中間件,如老牌的ActiveMQRabbitMQ,煊赫一時的Kafka,阿里巴巴自主開發RocketMQ等。分佈式

2.爲何要使用消息中間件?

 

回答這個問題,其實就是讓你先說說消息中間件的常見使用場景,而後結合大家自身系統對應的使用場景,說一下在大家系統中引入消息中間件是解決了什麼問題。

1) 系統解耦

 

假設你有個系統A,這個系統A會產出一個核心數據,如今下游有系統B和系統C須要這個數據。那簡單,系統A就是直接調用系統B和系統C的接口發送數據給他們就行了。

可是如今要是來了系統D、系統E、系統F、系統G,等等,十來個其餘系統慢慢的都須要這份核心數據呢?以下圖所示:

 

一個大規模系統,每每會拆分爲幾十個甚至上百個子系統,每一個子系統又對應N多個服務,這些系統與系統之間有着錯綜複雜的關係網絡。

若是某個系統產出一份核心數據,可能下游無數的其餘系統都須要這份數據來實現各類業務邏輯。

此時若是你要是採起上面那種模式來設計系統架構,那麼絕對你負責系統A的同窗要被煩死了。

先是來一我的找他要求發送數據給一個新的系統H,系統A的同窗要修改代碼而後在那個代碼里加入調用新系統H的流程。

一會那個系統B是個陳舊老系統要下線了,告訴系統A的同窗:別給我發送數據了,接着系統A再次修改代碼再也不給這個系統B。

而後若是要是某個下游系統忽然宕機了呢?

系統A的調用代碼裏是否是會拋異常?那系統A的同窗會收到報警說異常了,結果他還要去關注是下游哪一個系統宕機了。

因此在實際的系統架構設計中,若是所有采起這種系統耦合的方式,在某些場景下絕對是不合適的,系統耦合度太嚴重。

而且互相耦合起來並非核心鏈路的調用,而是一些非核心的場景(好比上述的數據消費,日誌等)致使了系統耦合,這樣會嚴重的影響上下游系統的開發和維護效率。

所以在上述系統架構中,就能夠採用MQ中間件來實現系統解耦。

系統A就把本身的一份核心數據發到MQ裏,下游哪一個系統感興趣本身去消費便可,不須要了就取消數據的消費,以下圖所示


 

 

 

2)異步調用

假設你有一個系統調用鏈路,是系統A調用系統B,通常耗時20ms;系統B調用系統C,通常耗時200ms;系統C調用系統D,通常耗時2s,以下圖所示:

 

如今最大的問題就是:

用戶一個請求過來巨慢無比,由於走完一個鏈路,須要耗費:

20ms + 200ms + 2000ms(2s) = 2220ms,

也就是2秒多的時間。可是實際上,鏈路中的系統A調用系統B,系統B調用系統C,這兩個步驟起來也就220ms。

就由於引入了系統C調用系統D這個步驟,致使最終鏈路執行時間是2秒多,直接將鏈路調用性能下降了10倍,這就是致使鏈路執行過慢的罪魁禍首。

那此時咱們能夠思考一下,是否是能夠將系統D從鏈路中抽離出去作成異步調用呢?

其實不少的業務場景是能夠容許異步調用的。

舉個例子:你平時點個外賣,咔嚓一會兒下訂單而後付款了,此時帳戶扣款、建立訂單、通知商家給你準備菜品。

接着,是否是須要找個騎手給你送餐?那這個找騎手的過程,是須要一套複雜算法來實現調度的,比較耗時。

可是其實稍微晚個幾十秒完成騎手的調度都是ok的,由於實際並不須要在你支付的一瞬間立馬給你找好騎手,也沒那個必要。

那麼咱們是否是就能夠把找騎手給你送餐的這個步驟從鏈路中抽離出去,作成異步化的,哪怕延遲個幾十秒,可是隻要在必定時間範圍內給你找到一個騎手去送餐就能夠了。

這樣是否是就可讓你下訂單點外賣的速度變得超快?支付成功以後,直接建立好訂單、帳戶扣款、通知商家立馬給你準備作菜就ok了,這個過程可能就幾百毫秒。

而後後臺異步化的耗費可能幾十秒經過調度算法給你找到一個騎手去送餐,可是這個步驟不影響咱們快速下訂單。

固然咱們不是說那些你們熟悉的外賣平臺的技術架構就必定是這麼實現的,只不過是用一個生活中常見的例子給你們舉例說明而已。

因此上面的鏈路也是同理,若是業務流程支持異步化的話,是否是就能夠考慮把系統C對系統D的調用抽離出去作成異步化的,不要放在鏈路中同步依次調用。

這樣,實現思路就是系統A -> 系統B -> 系統C,直接就耗費220ms後直接成功了。

而後系統C就是發送個消息到MQ中間件裏,由系統D消費到消息以後慢慢的異步來執行這個耗時2s的業務處理。經過這種方式直接將核心鏈路的執行性能提高了10倍。

整個過程,以下圖所示:

3)流量削峯

 

 

假設你有一個系統,平時正常的時候每秒可能就幾百個請求,系統部署在8核16G的機器的上,正常處理都是ok的,每秒幾百請求是能夠輕鬆抗住的,

可是如左圖所示,在高峯期一會兒來了每秒鐘幾千請求,瞬時出現了流量高峯,此時你的選擇是要搞10臺機器,抗住每秒幾千請求的瞬時高峯嗎?

那若是瞬時高峯天天就那麼半個小時,接着直接就下降爲了每秒就幾百請求,若是你線上部署了不少臺機器,那麼每臺機器就處理每秒幾十個請求就能夠了,這不是有點浪費機器資源嗎?

大部分時候,每秒幾百請求,一臺機器就足夠了,可是爲了抗那天天瞬時的高峯,硬是部署了10臺機器,天天就那半個小時有用,別的時候都是浪費資源的,以下圖

可是若是你就部署一臺機器,那會致使瞬時高峯時,一會兒壓垮你的系統,由於絕對沒法抗住每秒幾千的請求高峯。

此時咱們就能夠用MQ中間件來進行流量削峯。全部機器前面部署一層MQ,平時每秒幾百請求你們均可以輕鬆接收消息。

一旦到了瞬時高峯期,一下涌入每秒幾千的請求,就能夠積壓在MQ裏面,而後那一臺機器慢慢的處理和消費。

等高峯期過了,再消費一段時間,MQ裏積壓的數據就消費完畢了。

這個就是很典型的一個MQ的用法,用有限的機器資源承載高併發請求,若是業務場景容許異步削峯,高峯期積壓一些請求在MQ裏,而後高峯期過了,後臺系統在必定時間內消費完畢再也不積壓的話,那就很適合用這種技術方案。

 

3. 怎麼用消息中間件?

 

當前使用較多的 消息隊列 有 RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMQ 等,而部分 數據庫 如 Redis、MySQL也可實現消息隊列的功能

 

消息中間件組成

Broker:消息服務器,做爲server提供消息核心服務

Producer:消息生產者,業務的發起方,負責生產消息傳輸給broker,

Consumer:消息消費者,業務的處理方,負責從broker獲取消息並進行業務邏輯處理

Topic:主題,發佈訂閱模式下的消息統一聚集地,不一樣生產者向topic發送消息,由MQ服務器分發到不一樣的訂閱者,實現消息的廣播

Queue:隊列,點對點模式下,特定生產者向特定queue發送消息,消費者訂閱特定的queue完成指定消息的接收

Message:消息體,根據不一樣通訊協議定義的固定格式進行編碼的數據包,來封裝業務數據,實現消息的傳輸

消息中間件模式分類:

1)點對點:使用queue做爲通訊載體

說明: 
消息生產者生產消息發送到queue中,而後消息消費者從queue中取出而且消費消息。 
消息被消費之後,queue中再也不存儲,因此消息消費者不可能消費到已經被消費的消息。 Queue支持存在多個消費者,可是對一個消息而言,只會有一個消費者能夠消費

 

2) 發佈/訂閱

 

說明:

消息生產者(發佈)將消息發佈到topic中,同時有多個消息消費者(訂閱)消費該消息。和點對點方式不一樣,發佈到topic的消息會被全部訂閱者消費。

queue實現了負載均衡,將producer生產的消息發送到消息隊列中,由多個消費者消費。但一個消息只能被一個消費者接受,當沒有消費者可用時,這個消息會被保存直到有一個可用的消費者。

topic實現了發佈和訂閱,當你發佈一個消息,全部訂閱這個topic的服務都能獲得這個消息,因此從1到N個訂閱者都能獲得一個消息的拷貝。

相關文章
相關標籤/搜索