爲什麼要用消息隊列+各個消息隊列框架該如何選擇?

爲什麼要使用消息隊列

消息隊列中間件是分佈式系統中非常重要的分佈式架構,主要提供異步消息、流量消峯、應用解耦、消息通訊等功能。

1、異步處理

舉個例子:我們在某個系統網站中註冊賬號後,需要的操作爲將賬號信息添加進數據庫、發送註冊郵件、發送註冊短信,當這三個步驟全部完成後,返回個用戶註冊成功信息。
如果用串行方式處理,即先將信息插入到數據庫、然後發送郵件信息、發送註冊短信,最後返回給用戶註冊成功信息。假設每個流程將耗費50ms,不考慮其他消耗的時間,串行方式處理後,使用的總時間爲150ms。
如果用並行方式處理,即先將信息插入到數據庫、然後發送郵件信息和發送註冊短信進行並行處理,三步全部完成後,返回給用戶信息,使用的總時間爲100ms。
但是如果我們用消息隊列處理,即先將信息插入到數據庫、然後將接下來的操作放入消息隊列中,後面的操作由消息隊列來負責任務分配執行,通過消費者監聽,對接下來的兩步操作進行異步,由於放入消息隊列中的時間消耗非常短,我們可以忽略不計,同樣按照每個節點流程耗費50ms計算,並行處理方式的總共耗時幾乎等於將信息插入到數據庫中的時間,即50毫秒。

2、應用解耦

舉個例子:用戶下單後,訂單系統需要通知庫存系統。傳統的做法是,訂單系統調用庫存系統的接口。
但是這樣做會有一定的弊端,比如,訂單系統訂單成功,但是庫存系統異常,無法調用成功,這樣也將導致訂單系統的用戶下單失敗,訂單系統與庫存系統耦合嚴重,用戶體驗非常差。

此時我們就可以引入消息隊列,訂單系統訂單成功後,將消息存入到消息隊列中,存入成功後即可返回用戶下單成功。
庫存系統訂閱下單的消息,採用推拉的方式,獲取下單信息,庫存系統根據下單信息進行庫存操作。這樣一來就實現了訂單系統與庫存系統的解耦。

3、流量消峯

某電商網站開展秒殺活動,一般由於瞬間訪問暴增,服務器收到請求過大,可能出現無法處理請求或崩潰的情況。這時候我們可以應用rabbitmq做流量消峯處理,如果短時間流量過大,可以通過設置閥值丟棄掉一部分消息或者根據服務的承受能力設置處理消息限制,也就是限流。
在這裏插入圖片描述
同時,加入消息隊列後,系統就可以從消息隊列中讀取數據,相當於做了一次緩衝,超出系統處理之外的請求會積壓在消息隊列中,等高峯期已過,就會快速將積壓在隊列中的數據處理完。

消息隊列的缺陷

1、系統可用性降低

系統引入的外部依賴越多,越容易垮掉,原來整個系統是ABCD四個系統間的相互調用,引入mq之後,如果mq掛掉,那麼整套系統將會崩潰,這時候就需要我們採用一定策略保證消息隊列的高可用。

2、系統複雜度提高

加入mq之後,我們如何保證消息沒有重複消費?怎麼處理消息丟失的情況?怎樣保證消息傳遞的順序性?這些問題都會隨着我們業務難度的增加需要考慮的。

3、一致性問題

例如:ABCD四個系統,A系統處理完了直接返回成功了,用戶以爲這個請求發送成功了,但是,如果BCD三個系統進行異步處理時,BD系統寫庫成功,但是C系統寫庫失敗,這樣就無法保證數據一致了。

RabbitMQ/ActiveMQ/RocketMQ/Kafka對比

1、RabbitMq

RabbitMQ 2007年發佈,是一個在AMQP(高級消息隊列協議)基礎上完成的,可複用的企業消息系統,是當前最主流的消息中間件之一。

主要特性

可靠性: 提供了多種技術可以讓你在性能和可靠性之間進行權衡。這些技術包括持久性機制、投遞確認、發佈者證實和高可用性機制;

靈活的路由: 消息在到達隊列前是通過交換機進行路由的。RabbitMQ爲典型的路由邏輯提供了多種內置交換機類型。如果你有更復雜的路由需求,可以將這些交換機組合起來使用,你甚至可以實現自己的交換機類型,並且當做RabbitMQ的插件來使用;

消息集羣:在相同局域網中的多個RabbitMQ服務器可以聚合在一起,作爲一個獨立的邏輯代理來使用;

隊列高可用:隊列可以在集羣中的機器上進行鏡像,以確保在硬件問題下還保證消息安全;

多種協議的支持:支持多種消息隊列協議;

支持語言豐富:服務器端用Erlang語言編寫,支持只要是你能想到的所有編程語言;

管理界面: RabbitMQ有一個易用的用戶界面,使得用戶可以監控和管理消息Broker的許多方面;

跟蹤機制:如果消息異常,RabbitMQ提供消息跟蹤機制,使用者可以找出發生了什麼;

插件機制:提供了許多插件,來從多方面進行擴展,也可以編寫自己的插件;

安裝需求

使用RabbitMQ需要:

  • ErLang語言包
  • RabbitMQ安裝包

RabbitMQ可以運行在Erlang語言所支持的平臺之上。

優缺點

優點

由於erlang語言的特性,mq 性能較好,高併發;

健壯、穩定、易用、跨平臺、支持多種語言、文檔齊全;

有消息確認機制和持久化機制,可靠性高;

高度可定製的路由;

管理界面較豐富,在互聯網公司也有較大規模的應用;

社區活躍度高;

缺點

儘管結合erlang語言本身的併發優勢,性能較好,但是不利於做二次開發和維護;

實現了代理架構,意味着消息在發送到客戶端之前可以在中央節點上排隊。此特性使得RabbitMQ易於使用和部署,但是使得其運行速度較慢,因爲中央節點增加了延遲,消息封裝後也比較大;

需要學習比較複雜的接口和協議,學習和維護成本較高;

2、ActiveMQ

ActiveMQ是由Apache出品,ActiveMQ 是一個完全支持JMS1.1和J2EE 1.4規範的 JMS Provider實現。它非常快速,支持多種語言的客戶端和協議,而且可以非常容易的嵌入到企業的應用環境中,並有許多高級功能。

主要特性

服從 JMS 規範:JMS 規範提供了良好的標準和保證,包括:同步或異步的消息分發,一次和僅一次的消息分發,消息接收和訂閱等等。遵從 JMS 規範的好處在於,不論使用什麼 JMS 實現提供者,這些基礎特性都是可用的;

連接性:ActiveMQ 提供了廣泛的連接選項,支持的協議有:HTTP/S,IP 多播,SSL,STOMP,TCP,UDP,XMPP等等。對衆多協議的支持讓 ActiveMQ 擁有了很好的靈活性。

支持的協議種類多:OpenWire、STOMP、REST、XMPP、AMQP ;

持久化插件和安全插件:ActiveMQ 提供了多種持久化選擇。而且,ActiveMQ 的安全性也可以完全依據用戶需求進行自定義鑑權和授權;

支持的客戶端語言種類多:除了 Java 之外,還有:C/C++,.NET,Perl,PHP,Python,Ruby;

代理集羣:多個 ActiveMQ 代理可以組成一個集羣來提供服務;

異常簡單的管理:ActiveMQ 是以開發者思維被設計的。所以,它並不需要專門的管理員,因爲它提供了簡單又使用的管理特性。有很多方法可以監控 ActiveMQ 不同層面的數據,包括使用在 JConsole 或者 ActiveMQ 的Web Console 中使用 JMX,通過處理 JMX 的告警消息,通過使用命令行腳本,甚至可以通過監控各種類型的日誌。

安裝需求

使用ActiveMQ需要:

  • Java JDK
  • ActiveMQ安裝包

ActiveMQ可以運行在Java語言所支持的平臺之上。

優缺點

優點

跨平臺(JAVA編寫與平臺無關有,ActiveMQ幾乎可以運行在任何的JVM上)

可以用JDBC:可以將數據持久化到數據庫。雖然使用JDBC會降低ActiveMQ的性能,但是數據庫一直都是開發人員最熟悉的存儲介質。將消息存到數據庫,看得見摸得着。而且公司有專門的DBA去對數據庫進行調優,主從分離;

支持JMS :支持JMS的統一接口;

支持自動重連

有安全機制:支持基於shiro,jaas等多種安全配置機制,可以對Queue/Topic進行認證和授權。

監控完善:擁有完善的監控,包括Web Console,JMX,Shell命令行,Jolokia的REST API;

界面友善:提供的Web Console可以滿足大部分情況,還有很多第三方的組件可以使用,如hawtio;

缺點

社區活躍度不及RabbitMQ高;

根據其他用戶反饋,會出莫名其妙的問題,會丟失消息;

目前重心放到activemq6.0產品-apollo,對5.x的維護較少;

不適合用於上千個隊列的應用場景;

3、RocketMQ

RocketMQ出自 阿里公司的開源產品,用 Java 語言實現,在設計時參考了 Kafka,並做出了自己的一些改進,消息可靠性上比 Kafka 更好。RocketMQ在阿里集團被廣泛應用在訂單,交易,充值,流計算,消息推送,日誌流式處理,binglog分發等場景。

主要特性:

是一個隊列模型的消息中間件,具有高性能、高可靠、高實時、分佈式特點;

Producer、Consumer、隊列都可以分佈式;

Producer向一些隊列輪流發送消息,隊列集合稱爲Topic,Consumer如果做廣播消費,則一個consumer實例消費這個Topic對應的所有隊列,如果做集羣消費,則多個Consumer實例平均消費這個topic對應的隊列集合;

能夠保證嚴格的消息順序;

提供豐富的消息拉取模式;

高效的訂閱者水平擴展能力;

實時的消息訂閱機制;

億級消息堆積能力;

較少的依賴;

安裝需求

使用RocketMQ需要:

  • Java JDK
  • 安裝git、Maven
  • RocketMQ安裝包

RocketMQ可以運行在Java語言所支持的平臺之上。

優缺點

優點

單機支持 1 萬以上持久化隊列

RocketMQ 的所有消息都是持久化的,先寫入系統 PAGECACHE,然後刷盤,可以保證內存與磁盤都有一份數據,訪問時,直接從內存讀取。

模型簡單,接口易用(JMS 的接口很多場合並不太實用);

性能非常好,可以大量堆積消息在broker中;

支持多種消費,包括集羣消費、廣播消費等。

各個環節分佈式擴展設計,主從HA;

開發度較活躍,版本更新很快。

缺點:

支持的客戶端語言不多,目前是java及c++,其中c++不成熟;
RocketMQ社區關注度及成熟度也不及前兩者;
沒有web管理界面,提供了一個CLI(命令行界面)管理工具帶來查詢、管理和診斷各種問題;
沒有在 mq 核心中去實現JMS等接口;

4、Kafka

Apache Kafka是一個分佈式消息發佈訂閱系統。它最初由LinkedIn公司基於獨特的設計實現爲一個分佈式的提交日誌系統( a distributed commit log),之後成爲Apache項目的一部分。Kafka系統快速、可擴展並且可持久化。它的分區特性,可複製和可容錯都是其不錯的特性。

主要特性:

快速持久化,可以在O(1)的系統開銷下進行消息持久化;

高吞吐,在一臺普通的服務器上既可以達到10W/s的吞吐速率;

完全的分佈式系統,Broker、Producer、Consumer都原生自動支持分佈式,自動實現負載均衡;

支持同步和異步複製兩種HA;

支持數據批量發送和拉取;

zero-copy:減少IO操作步驟;

數據遷移、擴容對用戶透明;

無需停機即可擴展機器;

其他特性:嚴格的消息順序、豐富的消息拉取模型、高效訂閱者水平擴展、實時的消息訂閱、億級的消息堆積能力、定期刪除機制;

安裝需求

使用Kafka需要:

  • Java JDK
  • Kafka安裝包

優缺點

優點

客戶端語言豐富,支持java、.net、php、ruby、python、go等多種語言;

性能卓越,單機寫入TPS約在百萬條/秒,消息大小10個字節;

提供完全分佈式架構, 並有replica機制, 擁有較高的可用性和可靠性, 理論上支持消息無限堆積;

支持批量操作;

消費者採用Pull方式獲取消息, 消息有序, 通過控制能夠保證所有消息被消費且僅被消費一次;

有優秀的第三方Kafka Web管理界面Kafka-Manager;

在日誌領域比較成熟,被多家公司和多個開源項目使用;

缺點

Kafka單機超過64個隊列/分區,Load會發生明顯的飆高現象,隊列越多,load越高,發送消息響應時間變長

使用短輪詢方式,實時性取決於輪詢間隔時間;

消費失敗不支持重試;

支持消息順序,但是一臺代理宕機後,就會產生消息亂序;

社區更新較慢;

5、總結

一般業務系統要引入 MQ,最早大家都是用 ActiveMQ,但是現在大家用的不多了,沒經過大規模吞吐量場景的驗證,社區也不是很活躍,不推薦使用。

中小型公司,技術實力較爲一般,技術挑戰不是特別高,用 RabbitMQ 是不錯的選擇,大型公司,基礎架構研發實力較強,用 RocketMQ 是很好的選擇。

如果是高性能分佈式、大數據領域的實時計算、日誌採集等場景,用 Kafka 是業內標準。

廣泛來說,電商、金融等對事務性要求很高的,可以考慮RabbitMQ和RocketMQ,對性能要求高的可考慮Kafka。

參考文章:

消息隊列及常用消息隊列介紹
消息隊列如何選擇

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