從“消息隊列”到“服務總線”和“流處理平臺”


-     什麼是隊列?     -


隊列是一種先進先出的數據結構,特殊之處在於它只允許在隊列的前端(front)進行刪除操作,而在隊列的後端(rear)進行插入操作。


-     什麼是消息隊列?     -


消息隊列就是一個隊列結構的中間件,也就是說消息放入這個中間件之後就可以直接返回,並不需要系統立即處理,而另外會有一個程序讀取這些數據,並按順序進行逐次處理。

-     消息隊列的優勢     -


消息隊列的核心功能就是消息傳遞。但由於其異步性和消息存儲的特定,使消息隊列具備如下優勢:

1. 解耦
消息隊列在處理過程中間插入了一個隱含的、基於數據的接口層,兩邊的處理過程都要實現這一接口。這允許你獨立的擴展或修改兩邊的處理過程,只要確保它們遵守同樣的接口約束。

2. 冗餘
有時在處理數據的時候處理過程會失敗。除非數據被持久化,否則將永遠丟失。消息隊列把數據進行持久化直到它們已經被完全處理,通過這一方式規避了數據丟失風險。在被許多消息隊列所採用的"插入-獲取-刪除"範式中,在把一個消息從隊列中刪除之前,需要你的處理過程明確的指出該消息已經被處理完畢,確保你的數據被安全的保存直到你使用完畢。

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

4. 靈活性 & 峯值處理能力
在訪問量劇增的情況下,你的應用仍然需要繼續發揮作用,但是這樣的突發流量並不常見;如果爲以能處理這類峯值訪問爲標準來投入資源隨時待命無疑是巨大的浪費。使用消息隊列能夠使關鍵組件頂住增長的訪問壓力,而不是因爲超出負荷的請求而完全崩潰。

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

6. 送達保證
消息隊列提供的冗餘機制保證了消息能被實際的處理,只要一個進程讀取了該隊列即可。

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

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

9. 理解數據流
在一個分佈式系統裏,要得到一個關於用戶操作會用多長時間及其原因的總體印象,是個巨大的挑戰。消息系列通過消息被處理的頻率,來方便的輔助確定那些表現不佳的處理過程或領域,這些地方的數據流都不夠優化。

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

-     消息模板:如何發佈和獲取消息     -


JMS(Java Message Service,Java消息服務)API是一個消息服務的標準/規範,允許應用程序組件基於JavaEE平臺創建、發送、接收和讀取消息。 在JMS標準中,有兩種消息模型: P2P(Point to Point),Publish/Subscribe(Pub/Sub)。

搜索後端架構師公衆號回覆“架構整潔”,送你一份驚喜禮包。

Point-to-Point(PTP)模型


在P2P模型中,每個消息只有一個消費者(即一旦被消費,消息就不再在消息隊列中),隊列保留着消息,直到它們被消費或超時。發送者和接收者之間在時間上沒有依賴性,也就是說當發送者發送了消息之後,不管接收者有沒有正在運行,它不會影響到消息被髮送到隊列。接收者在成功接收消息之後需向隊列應答成功如果你希望發送的每個消息都應該被成功處理的話,那麼你需要P2P模型

Publisher/Subscriber (Pub/Sub) 模型
在Pub/Sub模型中包含如下概念:主題(Topic)、發佈者(Publisher)、訂閱者(Subscriber)。客戶端將消息發送到主題。多個發佈者將消息發送到Topic,系統將這些消息傳遞給多個訂閱者。


每個消息可以有多個消費者。發佈者和訂閱者之間有時間上的依賴性。針對某個主題(Topic)的訂閱者,它必須創建一個訂閱之後,才能消費發佈者的消息,而且,爲了消費消息,訂閱者必須保持運行的狀態。當然,爲了緩和這種嚴格的時間相關性,JMS允許訂閱者創建一個可持久化的訂閱。這樣,即使訂閱者沒有被激活(運行),它也能接收到發佈者的消息。如果你希望發送的消息可以不被做任何處理、或者被一個消費者處理、或者可以被多個消費者處理的話,那麼可以採用Pub/Sub模型。

-     何時使用消息隊列     -


消息隊列是軟件系統作信息傳遞和系統集成的主要手段,同時相對於使用消息隊列發送消息而言,還有另外一種更加普遍使用的集成技術,就是API。 兩者都具有廣泛的應用,所以在實際架構設計中,經常要考慮的問題是什麼時候使用API,什麼時候使用消息隊列。 下表列出兩者主要的區別:


如何判斷什麼時候該使用API,什麼時候該使用消息呢?舉個例子:

假設一個零售商開放他的產品清單。通過開放這個產品清單,合作廠商可以快速定位到自己的產品。產品清單中的數據是隻讀的,所以用戶可以重複的請求訪問。這種場景下,REST API使用簡單並且同步,更適合這個場景。

另一個場景,假設一個醫院要在治療病人之後更新病人的病歷。病歷信息對於醫院和病人來講都是非常關鍵的信息,爲了保證信息在傳輸過程中不會丟失,此時採用消息更加合適。

最後一個場景。假設一個零售商搭建一個應用允許合作廠商訪問他的產品清單並下訂單。這種情況下,可以同時使用API和消息。在查詢產品清單時,可以使用API。而在下訂單時,爲了避免消息丟失和處理峯值流量,可以使用消息隊列。

-     服務總線     -


消息總線可以理解成全局的消息通道。所以相對消息隊列而言,他的不同之處在於全局性和共享性。所以,消息總線會包含三部分:通用數據模型、通用指令集和消息隊列。跟隨SOA(Service Oriented Architecture,面向服務架構)的概念,信息系統的總線通常叫服務總線,企業層的總線稱之爲企業服務總線(ESB)。

企業服務總線可以看作是一種模式,在這種模式下定義了一個集中式的消息中間件實現各種後端系統的集成(包括數據模型轉換、連接、路由和編排),從而實現些集成服務可以在構建新應用時複用。

在SOA中,IT架構被分成組件層、Web服務層、業務流程層等。組件層包括各種應用系統,它們通常是技術相關的具體實現,各種具體的分佈式組件技術(CORBA、COM/DCOM、J2EE)都可以用於實現組件層的應用組件。通常複雜的IT環境中的組件層都同時使用了多種分佈式組件技術,而不同實現技術之間的互聯性障礙給應用集成帶來了極大的困難,進而形成了一個個信息孤島。


SOA引入了Web服務層來解決此種情況下的應用集成問題。Web服務是獨立於各種分佈式組件技術的,它使用標準的基於XML的服務描述語言(Web Service Description Language,WSDL)來定義和封裝離散的業務功能,各種支持Web服務的分佈式組件技術能夠將其上的業務組件發佈成Web服務併產生相應的WSDL文檔,並且只需要依據WSDL描述的信息就能夠調用Web服務,即WSDL所描述的業務功能。在SOA中,需要進入系統集成環節的業務組件都被映射爲Web服務,形成了Web服務層。業務流程層則處於Web服務層之上,通過對Web服務的流程編排來實現商業流程。業務流程層通過Web服務層能夠調用到基於各種分佈式組件技術實現的業務組件,實現了複雜IT系統環境的應用集成。

作爲SOA基礎架構的關鍵部分,ESB的功能主要體現在通信、服務交互、應用集成、服務質量、安全性以及管理和監控等方面。在通信方面,ESB能夠支持消息路由/尋址,支持多種通信技術、通信協議(如JMS、HTTP),支持發佈/訂閱的通信模式,能夠處理請求/響應、同步以及異步的消息傳遞方式,並且要求以可靠的方式傳遞消息。

 
常見的ESB產品包括:IBM的WebSphere ESB,Microsoft 基於BizTalk的ESB產品,JBOSS SOA Platform等。

需要強調的是,消息總線或企業服務總線的目的是爲了系統集成和服務共享。因此,當使用消息總線的時候,所有的服務或者應用必須共享相同的數據類型,指令集以及相同的通信協議,並且在消息總線中,會最大量消息轉換和編排的工作。而相對而言,消息隊列的目的是信息傳輸,因此並不限制是否類型一致。

-     流處理平臺——Kafka     -


市面上的消息隊列產品有很多,比如ActiveMQ、RabbitMQ 、Kafka 、RocketMQ ,還有 ZeroMQ ,連 redis 這樣的 NoSQL 數據庫也支持 MQ 功能。 但其中影響力最大的應該還是Kafka。 而從Kafka給自己的定義可以看出,Kafka不只是消息隊列,而是分佈式的流處理平臺。

什麼是流處理平臺呢?流處理是一種重要的大數據處理手段,其主要特點是其處理的數據是源源不斷且實時到來的。分佈式流處理是一種面向動態數據的細粒度處理模式,基於分佈式內存,對不斷產生的動態數據進行處理。其對數據處理的快速,高效,低延遲等特性,在大數據處理中發揮越來越重要的作用。流處理技術有很多技術選型,更多信息可以參考“Apache 的流處理技術概述”。僅從Kafka的角度看流處理平臺和消息隊列的區別,Kafka作爲流處理平臺具有以下三種特性:

可以讓你發佈和訂閱流式的記錄。這一方面與消息隊列或者消息總線類似。
可以儲存流式的記錄,並且有較好的容錯性。
可以在流式記錄產生時就進行處理。


但與基於隊列和交換的RabbitMQ不同,Kafka的存儲層是使用分區的事務日誌實現的。Kafka還提供用於實時處理流的Streams API和可輕鬆與各種數據源集成的Connector API。Kafka沒有“執行隊列”的概念。相反,Kafka將記錄的集合存儲在稱爲主題(Topic)的類別中。

對於每個主題,Kafka維護消息的分區日誌。每個分區都是一個有序的,不可變的記錄序列,在該記錄中連續附加消息。因此Kafka的實現十分適合“Publisher/Subscriber (Pub/Sub) 模型”,但不適合“Point-to-Point(PTP)模型”。因此Kafka的定位並非消息隊列或消息總線,而是流處理平臺。

因此,流處理平臺和消息隊列或消息總線最大的區別就是在消息隊列功能基礎上,流處理平臺更加關注對流數據分析的支持。

本文分享自微信公衆號 - 架構真經(gentoo666)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章