消息中間件(MQ)的定義前端
其實並無標準定義。通常認爲,消息中間件屬於分佈式系統中一個子系統,關注於數據的發送和接收,利用高效可靠的異步消息傳遞機制對分佈式系統中的其他各個子系統進行集成。數據庫
高效:對於消息的處理處理速度快。設計模式
可靠:通常消息中間件都會有消息持久化機制和其餘的機制確保消息不丟失。服務器
異步:指發送完一個請求,不須要等待返回,隨時能夠再發送下一個請求,既不須要等待。網絡
一句話總結,咱們消息中間件不生產消息,只是消息的搬運工。架構
假設一個電商交易的場景,用戶下單以後調用庫存系統減庫存,而後須要調用物流系統進行發貨,若是交易、庫存、物流是屬於一個系統的,那麼就是接口調用。可是隨着系統的發展,各個模塊愈來愈龐大、業務邏輯愈來愈複雜,必然是要作服務化和業務拆分的。這個時候就須要考慮這些系統之間如何交互,通常的處理方式就是 RPC(Remote Procedure Call)(具體實現 dubbo,SpringCloud)。系統繼續發展,可能一筆交易後續須要調用幾十個接口來執行業務,好比還有風控系統、短信服務等等。這個時候就須要消息中間件登場來解決問題了。併發
因此消息中間件主要解決分佈式系統之間消息的傳遞,同時爲分佈式系統中其餘子系統提供了鬆耦合的架構,同時還有如下好處:異步
低耦合,不論是程序仍是模塊之間,使用消息中間件進行間接通訊。分佈式
異步通訊能力,使得子系統之間得以充分執行本身的邏輯而無需等待。性能
緩衝能力,消息中間件像是一個巨大的蓄水池,將高峯期大量的請求存儲下來慢慢交給後臺進行處理,對於秒殺業務來講尤其重要。
伸縮性,是指經過不斷向集羣中加入服務器的手段來緩解不斷上升的用戶併發訪問壓力和不斷增加的數據存儲需求。就像彈簧同樣掛東西同樣,用戶多,伸一點,用戶少,淺一點,啊,不對,縮一點。是伸縮,不是深淺。衡量架構是否高伸縮性的主要標準就是是否可用多臺服務器構建集羣,是否容易向集羣中添加新的服務器。加入新的服務器後是否能夠提供和原來服務器無差異的服務。集羣中可容納的總的服務器數量是否有限制。
擴展性,主要標準就是在網站增長新的業務產品時,是否能夠實現對現有產品透明無影響,不須要任何改動或者不多改動既有業務功能就能夠上線新產品。好比用戶購買電影票的應用,如今咱們要增長一個功能,用戶買了鐵血戰士的票後,隨機抽取用戶送異形的限量周邊。怎麼作到不改動用戶購票功能的基礎上增長這個功能。熟悉設計模式的同窗,應該很眼熟,這是設計模式中的開閉原則(對擴展開放,對修改關閉)在架構層面的一個原則。
RPC 和消息中間件的場景的差別很大程度上在於就是「依賴性」和「同步性」。
依賴性:
好比短信通知服務並非事交易環節必須的,並不影響下單流程,不是強依賴,因此交易系統不該該依賴短信服務。若是是 RPC 調用,短信通知服務掛了,整個業務就掛了,這個就是依賴性致使的,而消息中間件則沒有這個依賴性。
消息中間件出現之後對於交易場景多是調用庫存中心等強依賴系統執行業務,以後發佈一條消息(這條消息存儲於消息中間件中)。像是短信通知服務、數據統計服務等等都是依賴於消息中間件去消費這條消息來完成本身的業務邏輯。
同步性:
RPC 方式是典型的同步方式,讓遠程調用像本地調用。消息中間件方式屬於異步方式。
相同點:都是分佈式下面的通訊方式。
場景說明:用戶註冊後,須要發註冊郵件和註冊短信。傳統的作法有兩種 1.串行的方式;2.並行方式。
串行方式:將註冊信息寫入數據庫成功後,發送註冊郵件,再發送註冊短信。以上三個任務所有完成後,返回給客戶端。
(2)並行方式:將註冊信息寫入數據庫成功後,發送註冊郵件的同時,發送註冊短信。以上三個任務完成後,返回給客戶端。與串行的差異是,並行的方式能夠提升處理的時間。
假設三個業務節點每一個使用 50 毫秒鐘,不考慮網絡等其餘開銷,則串行方式的時間是 150 毫秒,並行的時間多是 100 毫秒。
小結:如以上案例描述,傳統的方式系統的性能(併發量,吞吐量,響應時間)會有瓶頸。如何解決這個問題呢?
引入消息隊列,將不是必須的業務邏輯,異步處理。
按照以上約定,用戶的響應時間至關因而註冊信息寫入數據庫的時間,也就是 50 毫秒。註冊郵件,發送短信寫入消息隊列後,直接返回,所以寫入消息隊列的速度很快,基本能夠忽略,所以用戶的響應時間多是 50 毫秒。所以架構改變後,系統的吞吐量提升到每秒 20 QPS。比串行提升了 3 倍,比並行提升了兩倍。
場景說明:用戶下單後,訂單系統須要通知庫存系統。傳統的作法是,訂單系統調用庫存系統的接口。
傳統模式的缺點:
1) 假如庫存系統沒法訪問,則訂單減庫存將失敗,從而致使訂單失敗;
2) 訂單系統與庫存系統耦合;
如何解決以上問題呢?引入應用消息隊列後的方案
訂單系統:用戶下單後,訂單系統完成持久化處理,將消息寫入消息隊列,返回用戶訂單下單成功。
庫存系統:訂閱下單的消息,採用拉/推的方式,獲取下單信息,庫存系統根據下單信息,進行庫存操做。
假如:在下單時庫存系統不能正常使用。也不影響正常下單,由於下單後,訂單系統寫入消息隊列就再也不關心其餘的後續操做了。實現訂單系統與庫存系統的應用解耦。
流量削峯也是消息隊列中的經常使用場景,通常在秒殺或團搶活動中使用普遍。
應用場景:秒殺活動,通常會由於流量過大,致使流量暴增,應用掛掉。爲解決這個問題,通常須要在應用前端加入消息隊列:能夠控制活動的人數;能夠緩解短期內高流量壓垮應用。
用戶的請求,服務器接收後,首先寫入消息隊列。假如消息隊列長度超過最大數量,則直接拋棄用戶請求或跳轉到錯誤頁面;秒殺業務根據消息隊列中的請求信息,再作後續處理。
日誌處理是指將消息隊列用在日誌處理中,好比 Kafka 的應用,解決大量日誌傳輸的問題。架構簡化以下:
日誌採集客戶端,負責日誌數據採集,定時寫入 Kafka隊列:Kafka 消息隊列,負責日誌數據的接收,存儲和轉發;日誌處理應用:訂閱並消費 kafka隊列中的日誌數據;
消息通信是指,消息隊列通常都內置了高效的通訊機制,所以也能夠用在純的消息通信。好比實現點對點消息隊列,或者聊天室等。
點對點通信:客戶端 A 和客戶端 B 使用同一隊列,進行消息通信。
聊天室通信:客戶端 A,客戶端 B,客戶端 N 訂閱同一主題,進行消息發佈和接收。實現相似聊天室效果。
卡夫卡與法國做家馬塞爾·普魯斯特,愛爾蘭做家詹姆斯·喬伊斯並稱爲西方現代主義文學的先驅和大師。《變形記》是卡夫卡的短篇表明做,是卡夫卡的藝術成就中的一座高峯,被認爲是 20 世紀最偉大的小說做品之一。
若是通常的業務系統要引入 MQ,怎麼選型:
用戶訪問量在 ActiveMQ 的可承受範圍內,並且確實主要是基於解耦和異步來用的,能夠考慮 ActiveMQ,也比較貼近 Java 工程師的使用習慣,可是ActiveMQ 如今中止維護了,同時 ActiveMQ 併發不高,因此業務量必定的狀況下能夠考慮使用。
RabbitMQ 做爲一個純正血統的消息中間件,有着高級消息協議 AMQP 的完美結合,在消息中間件中地位無可取代,可是 erlang 語言阻止了咱們去深刻研究和掌控,對公司而言,底層技術沒法控制,可是確實是開源的,有比較穩定的支持,活躍度也高。
對本身公司技術實力有絕對自信的,能夠用 RocketMQ 。
因此中小型公司,技術實力較爲通常,技術挑戰不是特別高,用 ActiveMQ、RabbitMQ 是不錯的選擇;大型公司,基礎架構研發實力較強,用 RocketMQ是很好的選擇
若是是大數據領域的實時計算、日誌採集等場景,用 Kafka 是業內標準的,絕對沒問題,社區活躍度很高,幾乎是全世界這個領域的事實性規範。
總體上來看,使用文件系統的消息中間件(kafka、rokcetMq)性能是最好的,因此基於文件系統存儲的消息中間件是發展趨勢。(從存儲方式和效率來看 文件系統>KV 存儲>關係型數據庫)