訊息佇列深入解析

SnailClimb發表於2018-04-21

訊息佇列和訊息

“訊息佇列”(Message queue)是在訊息的傳輸過程中儲存訊息的容器。“訊息” 是在兩臺計算機間傳送的資料單位。訊息可以非常簡單,例如只包含文字字串;也可以更復雜,可能包含嵌入物件。

常見的訊息佇列有那些?

當前使用較多的訊息佇列有RabbitMQActiveMQRocketMQKafka等等,我們之前提高的redis資料庫也可以實現訊息佇列,不過不推薦,redis本身設計就不是用來做訊息佇列的。

使用訊息佇列的場景和好處

《大型網站技術架構》第四章和第七章均有提到訊息佇列對應用效能及擴充套件性的提升。

1.通過非同步處理提高系統效能

通過非同步處理提高系統效能
如上圖,在不使用訊息佇列伺服器的時候,使用者的請求資料直接寫入資料庫,在高併發的情況下資料庫壓力劇增,使得響應速度變慢。但是在使用訊息佇列之後,使用者的請求資料傳送給訊息佇列之後立即 返回,再由訊息佇列的消費者程式從訊息佇列中獲取資料,非同步寫入資料庫。由於訊息佇列伺服器處理速度快於資料庫(訊息佇列也比資料庫有更好的伸縮性),因此響應速度得到大幅改善。

通過以上分析我們可以得出訊息佇列具有很好的削峰作用的功能——即通過非同步處理,將短時間高併發產生的事務訊息儲存在訊息佇列中,從而削平高峰期的併發事務。 舉例:在電子商務一些秒殺、促銷活動中,合理使用訊息佇列可以有效抵禦促銷活動剛開始大量訂單湧入對系統的衝擊。如下圖所示:

合理使用訊息佇列可以有效抵禦促銷活動剛開始大量訂單湧入對系統的衝擊
因為使用者請求資料寫入訊息佇列之後就立即返回給使用者了,但是請求資料在後續的業務校驗、寫資料庫等操作中可能失敗。因此使用訊息佇列進行非同步處理之後,需要適當修改業務流程進行配合,比如使用者在提交訂單之後,訂單資料寫入訊息佇列,不能立即返回使用者訂單提交成功,需要在訊息佇列的訂單消費者程式真正處理完該訂單之後,甚至出庫後,再通過電子郵件或簡訊通知使用者訂單成功,以免交易糾紛。這就類似我們平時手機訂火車票和電影票。

2.降低系統耦合性

我們知道模組分散式部署以後聚合方式通常有兩種:1.分散式訊息佇列和2.分散式服務

先來簡單說一下分散式服務:

目前使用比較多的用來構建SOA(Service Oriented Architecture面向服務體系結構)分散式服務框架是阿里巴巴開源的Dubbo.如果想深入瞭解Dubbo的可以看我寫的關於Dubbo的這一篇文章:《高效能優秀的服務框架-dubbo介紹》juejin.im/post/5acade…

再來談我們的分散式訊息佇列:

我們知道如果模組之間不存在直接呼叫,那麼新增模組或者修改模組就對其他模組影響較小,這樣系統的可擴充套件性無疑更好一些。

我們最常見的事件驅動架構類似生產者消費者模式,在大型網站中通常用利用訊息佇列實現事件驅動結構。如下圖所示:

利用訊息佇列實現事件驅動結構
訊息佇列使利用釋出-訂閱模式工作,訊息傳送者(生產者)釋出訊息,一個或多個訊息接受者(消費者)訂閱訊息。 從上圖可以看到訊息傳送者(生產者)和訊息接受者(消費者)之間沒有直接耦合,訊息傳送者將訊息傳送至分散式訊息佇列即結束對訊息的處理,訊息接受者從分散式訊息佇列獲取該訊息後進行後續處理,並不需要知道該訊息從何而來。對新增業務,只要對該類訊息感興趣,即可訂閱該訊息,對原有系統和業務沒有任何影響,從而實現網站業務的可擴充套件性設計

訊息接受者對訊息進行過濾、處理、包裝後,構造成一個新的訊息型別,將訊息繼續傳送出去,等待其他訊息接受者訂閱該訊息。因此基於事件(訊息物件)驅動的業務架構可以是一系列流程。

另外為了避免訊息佇列伺服器當機造成訊息丟失,會將成功傳送到訊息佇列的訊息儲存在訊息生產者伺服器上,等訊息真正被消費者伺服器處理後才刪除訊息。在訊息佇列伺服器當機後,生產者伺服器會選擇分散式訊息佇列伺服器叢集中的其他伺服器釋出訊息。

備註: 不要認為訊息佇列只能利用釋出-訂閱模式工作,只不過在解耦這個特定業務環境下是使用釋出-訂閱模式的,比如在我們的ActiveMQ訊息佇列中還有點對點工作模式,具體的會在後面的文章給大家詳細介紹,這一篇文章主要還是讓大家對訊息佇列有一個更透徹的瞭解。

常見的訊息佇列介紹

1.ActiveMQ

官網:activemq.apache.org/

簡介:

ActiveMQ 是Apache出品,最流行的,能力強勁的開源訊息匯流排。ActiveMQ 是一個完全支援JMS1.1和J2EE 1.4規範的 JMS Provider實現,儘管JMS規範出臺已經是很久的事情了,但是JMS在當今的J2EE應用中間仍然扮演著特殊的地位。

特點:

  1. 支援來自Java,C,C ++,C#,Ruby,Perl,Python,PHP的各種跨語言客戶端和協議
  2. 完全支援JMS客戶端和Message Broker中的企業整合模式
  3. 支援許多高階功能,如訊息組,虛擬目標,萬用字元和複合目標
  4. 完全支援JMS 1.1和J2EE 1.4,支援瞬態,持久,事務和XA訊息
  5. Spring支援,以便ActiveMQ可以輕鬆嵌入到Spring應用程式中,並使用Spring的XML配置機制進行配置
  6. 專為高效能叢集,客戶端 - 伺服器,基於對等的通訊而設計
  7. CXF和Axis支援,以便ActiveMQ可以輕鬆地放入這些Web服務堆疊中以提供可靠的訊息傳遞
  8. 可以用作記憶體JMS提供程式,非常適合單元測試JMS
  9. 支援可插拔傳輸協議,例如in-VM,TCP,SSL,NIO,UDP,多播,JGroups和JXTA傳輸
  10. 使用JDBC和高效能日誌支援非常快速的永續性

2.RabbitMQ

官網:www.rabbitmq.com/

簡介:

RabbitMQ 是一個由 Erlang 語言開發的 AMQP 的開源實現。RabbitMQ輕巧且易於部署在雲端。 它支援多種訊息傳遞協議。 RabbitMQ可以部署在分散式和聯合配置中,以滿足高規模,高可用性需求。RabbitMQ可執行在許多作業系統和雲環境中,併為大多數流行語言提供廣泛的開發工具。(來自官網翻譯)

AMQP (Advanced MessageQueue):高階訊息佇列協議。它是應用層協議的一個開放標準,為面向訊息的中介軟體設計,基於此協議的客戶端與訊息中介軟體可傳遞訊息,並不受產品、開發語言等條件的限制。

RabbitMQ最初廣泛應用於金融行業,根據官網描述,它具有如下特點:

特點:

  1. 非同步訊息傳遞:支援多種訊息協議,訊息佇列,傳送確認,靈活的路由到佇列,多種交換型別;
  2. 支援幾乎所有最受歡迎的程式語言:Java,C,C ++,C#,Ruby,Perl,Python,PHP等等;
  3. 可以部署為高可用性和吞吐量的叢集; 跨多個可用區域和區域進行聯合;
  4. 可插入的身份驗證,授權,支援TLS和LDAP。;
  5. 提供了一個易用的使用者介面,使得使用者可以監控和管理訊息 Broker 的許多方面;
  6. 提供了許多外掛,來從多方面進行擴充套件,也可以編寫自己的外掛。

3. Kafka

官網:kafka.apache.org/

簡介:

Kafka是由Apache軟體基金會開發的一個開源流處理平臺,由Scala和Java編寫。Kafka是一種高吞吐量的分散式釋出訂閱訊息系統,它可以處理消費者規模的網站中的所有動作流資料。 這種動作(網頁瀏覽,搜尋和其他使用者的行動)是在現代網路上的許多社會功能的一個關鍵因素。 這些資料通常是由於吞吐量的要求而通過處理日誌和日誌聚合來解決。 對於像Hadoop的一樣的日誌資料和離線分析系統,但又要求實時處理的限制,這是一個可行的解決方案。Kafka的目的是通過Hadoop的並行載入機制來統一線上和離線的訊息處理,也是為了通過叢集來提供實時的訊息。

Kafka它主要用於處理活躍的流式資料,因此Kafaka在大資料系統中使用較多。

特點:

  1. 同時為釋出和訂閱提供高吞吐量。據瞭解,Kafka每秒可以生產約25萬訊息(50 MB),每秒處理55萬訊息(110 MB)。
  2. 可進行持久化操作。將訊息持久化到磁碟,因此可用於批量消費,例如ETL,以及實時應用程式。通過將資料持久化到硬碟以及replication防止資料丟失。
  3. 分散式系統,易於向外擴充套件。所有的producer、broker和consumer都會有多個,均為分散式的。無需停機即可擴充套件機器。
  4. 訊息被處理的狀態是在consumer端維護,而不是由server端維護。當失敗時能自動平衡。
  5. 支援online和offline的場景。

4. RocketMQ

官網:rocketmq.apache.org/

簡介:

RocketMQ是阿里開源的訊息中介軟體,目前在Apache孵化,使用純Java開發,具有高吞吐量、高可用性、適合大規模分散式系統應用的特點。RocketMQ思路起源於Kafka,但並不是簡單的複製,它對訊息的可靠傳輸及事務性做了優化,目前在阿里集團被廣泛應用於交易、充值、流計算、訊息推送、日誌流式處理、binglog分發等場景,支撐了阿里多次雙十一活動。

特點:

  1. 支援釋出/訂閱(Pub/Sub)和點對點(P2P)訊息模型
  2. 在一個佇列中可靠的先進先出(FIFO)和嚴格的順序傳遞
  3. 支援拉(pull)和推(push)兩種訊息模式
  4. 單一佇列百萬訊息的堆積能力
  5. 支援多種訊息協議,如 JMS、MQTT 等
  6. 分散式高可用的部署架構,滿足至少一次訊息傳遞語義
  7. 提供 docker 映象用於隔離測試和雲叢集部署
  8. 提供配置、指標和監控等功能豐富的 Dashboard

區別(圖片來源慕課網):

訊息佇列深入解析
其實對於這些訊息佇列的產品,每一種都在某一領域佔有一席,雖然ActiveMQ目前在社群已經不是很活躍,但是其下一代產品Apollo已經問世。ZeroMQ小而美,RabbitMQ大而穩,Kakfa和RocketMQ快而強勁。RocketMQ雖然目前還很多不完善,但是一旦在Apache孵化成為頂級專案,全球程式猿開始貢獻,前途也是不可限量的。

下一篇文章我會詳細介紹ActiveMQ以及相關使用方法。

歡迎關注我的微信公眾號:"Java面試通關手冊"(一個有溫度的微信公眾號,期待與你共同進步~~~堅持原創,分享美文,分享各種Java學習資源):

微信公眾號

相關文章