【消息隊列】--- 消息隊列的使用場景

 文章整理自知乎:https://www.zhihu.com/question/34243607docker

【解釋一】:

我的認爲消息隊列的主要特色是異步處理,主要目的是減小請求響應時間和解耦。因此主要的使用場景就是將比較耗時並且不須要即時(同步)返回結果的操做做爲消息放入消息隊列。同時因爲使用了消息隊列,只要保證消息格式不變,消息的發送方和接收方並不須要彼此聯繫,也不須要受對方的影響,即解耦和數據庫

使用場景的話,舉個例子:
假設用戶在你的軟件中註冊,服務端收到用戶的註冊請求後,它會作這些操做:
  1. 校驗用戶名等信息,若是沒問題會在數據庫中添加一個用戶記錄
  2. 若是是用郵箱註冊會給你發送一封註冊成功的郵件,手機註冊則會發送一條短信
  3. 分析用戶的我的信息,以便未來向他推薦一些志同道合的人,或向那些人推薦他
  4. 發送給用戶一個包含操做指南的系統通知
  5. 等等……

可是對於用戶來講,註冊功能實際只須要第一步,只要服務端將他的帳戶信息存到數據庫中他即可以登陸上去作他想作的事情了。至於其餘的事情,非要在這一次請求中所有完成麼?值得用戶浪費時間等你處理這些對他來講可有可無的事情麼?因此實際當第一步作完後,服務端就能夠把其餘的操做放入對應的消息隊列中而後立刻返回用戶結果,由消息隊列異步的進行這些操做apache

或者還有一種狀況,同時有大量用戶註冊你的軟件,在高併發狀況下注冊請求開始出現一些問題,例如郵件接口承受不住,或是分析信息時的大量計算使cpu滿載,這將會出現雖然用戶數據記錄很快的添加到數據庫中了,可是卻卡在發郵件或分析信息時的狀況,致使請求的響應時間大幅增加,甚至出現超時,這就有點不划算了。面對這種狀況通常也是將這些操做放入消息隊列(生產者消費者模型),消息隊列慢慢的進行處理,同時能夠很快的完成註冊請求,不會影響用戶使用其餘功能。編程

因此在軟件的正常功能開發中,並 不須要去刻意的尋找消息隊列的使用場景,而是當出現性能瓶頸時,去查看業務邏輯是否存在能夠異步處理的耗時操做,若是存在的話即可以引入消息隊列來解決。不然盲目的使用消息隊列可能會增長維護和開發的成本卻沒法獲得可觀的性能提高,那就得不償失了。
 
【解釋二】:
 
「消息隊列」(Message queue)是在消息的傳輸過程當中保存消息的容器。「消息」 是在兩臺計算機間傳送的數據單位。消息能夠很是簡單,例如只包含文本字符串;也能夠更復雜,可能包含嵌入對象。

使用消息隊列的場景和好處

《大型網站技術架構》第四章和第七章均有提到消息隊列對應用性能及擴展性的提高。服務器

1.經過異步處理提升系統性能

如上圖,在不使用消息隊列服務器的時候,用戶的請求數據直接寫入數據庫,在高併發的狀況下數據庫壓力劇增,使得響應速度變慢。可是在使用消息隊列以後,用戶的請求數據發送給消息隊列以後當即返回,再由消息隊列的消費者進程從消息隊列中獲取數據,異步寫入數據庫。因爲消息隊列服務器處理速度快於數據庫(消息隊列也比數據庫有更好的伸縮性),所以響應速度獲得大幅改善。網絡

經過以上分析咱們能夠得出消息隊列具備很好的削峯做用的功能——即經過異步處理,將短期高併發產生的事務消息存儲在消息隊列中,從而削平高峯期的併發事務 舉例:在電子商務一些秒殺、促銷活動中,合理使用消息隊列能夠有效抵禦促銷活動剛開始大量訂單涌入對系統的衝擊。以下圖所示:架構

由於用戶請求數據寫入消息隊列以後就當即返回給用戶了,可是請求數據在後續的業務校驗、寫數據庫等操做中可能失敗。所以使用消息隊列進行異步處理以後,須要適當修改業務流程進行配合,好比用戶在提交訂單以後,訂單數據寫入消息隊列,不能當即返回用戶訂單提交成功,須要在消息隊列的訂單消費者進程真正處理完該訂單以後,甚至出庫後,再經過電子郵件或短信通知用戶訂單成功,以避免交易糾紛。這就相似咱們平時手機訂火車票和電影票。併發

2.下降系統耦合性

咱們知道模塊分佈式部署之後聚合方式一般有兩種:1.分佈式消息隊列和2.分佈式服務。框架

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

目前使用比較多的用來構建SOA(Service Oriented Architecture面向服務體系結構)分佈式服務框架是阿里巴巴開源的Dubbo.若是想深刻了解Dubbo的能夠看我寫的關於Dubbo的這一篇文章:《高性能優秀的服務框架-dubbo介紹》異步

再來談咱們的分佈式消息隊列:

咱們知道若是模塊之間不存在直接調用,那麼新增模塊或者修改模塊就對其餘模塊影響較小,這樣系統的可擴展性無疑更好一些。

咱們最多見的事件驅動架構相似生產者消費者模式,在大型網站中一般用利用消息隊列實現事件驅動結構。以下圖所示:

做者:Snailclimb
連接:https://www.zhihu.com/question/34243607/answer/372537590
來源:知乎
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。

消息隊列使利用發佈-訂閱模式工做,消息發送者(生產者)發佈消息,一個或多個消息接受者(消費者)訂閱消息。 從上圖能夠看到消息發送者(生產者)和消息接受者(消費者)之間沒有直接耦合,消息發送者將消息發送至分佈式消息隊列即結束對消息的處理,消息接受者從分佈式消息隊列獲取該消息後進行後續處理,並不須要知道該消息從何而來。對新增業務,只要對該類消息感興趣,便可訂閱該消息,對原有系統和業務沒有任何影響,從而實現網站業務的可擴展性設計

消息接受者對消息進行過濾、處理、包裝後,構形成一個新的消息類型,將消息繼續發送出去,等待其餘消息接受者訂閱該消息。所以基於事件(消息對象)驅動的業務架構能夠是一系列流程。

另外爲了不消息隊列服務器宕機形成消息丟失,會將成功發送到消息隊列的消息存儲在消息生產者服務器上,等消息真正被消費者服務器處理後才刪除消息。在消息隊列服務器宕機後,生產者服務器會選擇分佈式消息隊列服務器集羣中的其餘服務器發佈消息。

備註: 不要認爲消息隊列只能利用發佈-訂閱模式工做,只不過在解耦這個特定業務環境下是使用發佈-訂閱模式的,好比在咱們的ActiveMQ消息隊列中還有點對點工做模式,具體的會在後面的文章給你們詳細介紹,這一篇文章主要仍是讓你們對消息隊列有一個更透徹的瞭解。

常見的消息隊列介紹

1.ActiveMQ

官網:

簡介:

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

官網:

簡介:

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軟件基金會開發的一個開源流處理平臺,由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孵化,使用純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孵化成爲頂級項目,全球程序猿開始貢獻,前途也是不可限量的。

相關文章
相關標籤/搜索