「消息隊列」(Message queue)是在消息的傳輸過程當中保存消息的容器。「消息」 是在兩臺計算機間傳送的數據單位。消息能夠很是簡單,例如只包含文本字符串;也能夠更復雜,可能包含嵌入對象。面試
當前使用較多的消息隊列有RabbitMQ、ActiveMQ、RocketMQ、Kafka等等,咱們以前提升的redis數據庫也能夠實現消息隊列,不過不推薦,redis自己設計就不是用來作消息隊列的。redis
《大型網站技術架構》第四章和第七章均有提到消息隊列對應用性能及擴展性的提高。docker
如上圖,在不使用消息隊列服務器的時候,用戶的請求數據直接寫入數據庫,在高併發的狀況下數據庫壓力劇增,使得響應速度變慢。可是在使用消息隊列以後,用戶的請求數據發送給消息隊列以後當即 返回,再由消息隊列的消費者進程從消息隊列中獲取數據,異步寫入數據庫。因爲消息隊列服務器處理速度快於數據庫(消息隊列也比數據庫有更好的伸縮性),所以響應速度獲得大幅改善。數據庫
經過以上分析咱們能夠得出消息隊列具備很好的削峯做用的功能——即經過異步處理,將短期高併發產生的事務消息存儲在消息隊列中,從而削平高峯期的併發事務。 舉例:在電子商務一些秒殺、促銷活動中,合理使用消息隊列能夠有效抵禦促銷活動剛開始大量訂單涌入對系統的衝擊。以下圖所示:
由於用戶請求數據寫入消息隊列以後就當即返回給用戶了,可是請求數據在後續的業務校驗、寫數據庫等操做中可能失敗。所以使用消息隊列進行異步處理以後,須要適當修改業務流程進行配合,好比用戶在提交訂單以後,訂單數據寫入消息隊列,不能當即返回用戶訂單提交成功,須要在消息隊列的訂單消費者進程真正處理完該訂單以後,甚至出庫後,再經過電子郵件或短信通知用戶訂單成功,以避免交易糾紛。這就相似咱們平時手機訂火車票和電影票。apache
咱們知道模塊分佈式部署之後聚合方式一般有兩種:1.分佈式消息隊列和2.分佈式服務。編程
先來簡單說一下分佈式服務:服務器
目前使用比較多的用來構建SOA(Service Oriented Architecture面向服務體系結構)的分佈式服務框架是阿里巴巴開源的Dubbo.若是想深刻了解Dubbo的能夠看我寫的關於Dubbo的這一篇文章:《高性能優秀的服務框架-dubbo介紹》:http://www.javashuo.com/article/p-elojngof-dp.html微信
再來談咱們的分佈式消息隊列:網絡
咱們知道若是模塊之間不存在直接調用,那麼新增模塊或者修改模塊就對其餘模塊影響較小,這樣系統的可擴展性無疑更好一些。架構
咱們最多見的事件驅動架構相似生產者消費者模式,在大型網站中一般用利用消息隊列實現事件驅動結構。以下圖所示:
消息隊列使利用發佈-訂閱模式工做,消息發送者(生產者)發佈消息,一個或多個消息接受者(消費者)訂閱消息。 從上圖能夠看到消息發送者(生產者)和消息接受者(消費者)之間沒有直接耦合,消息發送者將消息發送至分佈式消息隊列即結束對消息的處理,消息接受者從分佈式消息隊列獲取該消息後進行後續處理,並不須要知道該消息從何而來。對新增業務,只要對該類消息感興趣,便可訂閱該消息,對原有系統和業務沒有任何影響,從而實現網站業務的可擴展性設計。
消息接受者對消息進行過濾、處理、包裝後,構形成一個新的消息類型,將消息繼續發送出去,等待其餘消息接受者訂閱該消息。所以基於事件(消息對象)驅動的業務架構能夠是一系列流程。
另外爲了不消息隊列服務器宕機形成消息丟失,會將成功發送到消息隊列的消息存儲在消息生產者服務器上,等消息真正被消費者服務器處理後才刪除消息。在消息隊列服務器宕機後,生產者服務器會選擇分佈式消息隊列服務器集羣中的其餘服務器發佈消息。
備註: 不要認爲消息隊列只能利用發佈-訂閱模式工做,只不過在解耦這個特定業務環境下是使用發佈-訂閱模式的,好比在咱們的ActiveMQ消息隊列中還有點對點工做模式,具體的會在後面的文章給你們詳細介紹,這一篇文章主要仍是讓你們對消息隊列有一個更透徹的瞭解。
官網:http://activemq.apache.org/
簡介:
ActiveMQ 是Apache出品,最流行的,能力強勁的開源消息總線。ActiveMQ 是一個徹底支持JMS1.1和J2EE 1.4規範的 JMS Provider實現,儘管JMS規範出臺已是好久的事情了,可是JMS在當今的J2EE應用中間仍然扮演着特殊的地位。
特色:
簡介:
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. 提供了許多插件,來從多方面進行擴展,也能夠編寫本身的插件。
簡介:
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的場景。
官網:http://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學習資源):。