解耦:分佈式開發中一個A系統產生的數據可能要發送給別的B系統使用,後續C系統,D系統可能也要A的數據,這樣豈不是每次都要對A系統進行變動,是不合理的,當把A系統的數據直接發送到MQ,後續任何系統需要數據到MQ訂閱,這樣就達到解耦的目的了;
削峯:針對如秒殺等類似的情景,系統的存取量大部分時間穩定,但是有一段時間存取量突增如果直接存取數據庫的話,很可能導致系統直接崩潰,這樣肯定不可以啦,用MQ就可以對高峯期的數據勻速處理,達到系統的高可用;
非同步:高併發情景下,同步處理容易發生阻塞或者堆積,採用MQ相當於在系統前加一道屏障進行非同步處理,降低系統壓力。
引入新技術會提高系統的複雜性、降低系統的可用性、保證一致性也是一個挑戰。
降低可用性:引入MQ,MQ如果掛了會引發後續系統不能繼續工作,所以應當儘可能的保證MQ的高可用;
提高系統複雜性:比如訊息重複消費問題、訊息的消費順序能否保證、訊息丟失問題;
保證一致性:多個系統的業務處理要麼都成功,要麼都失敗;
後續會根據MQ的不同選擇加以說明,由於目前只用過activeMQ和rocketMQ,所以會就這兩種MQ進行回答和記錄。
常見的MQ有activeMQ、rabbitMQ、rocketMQ、kafka;
這麼多可選擇的MQ,當然我們也要根據實際情況進行選擇,那麼可以從哪些維度進行考量呢?
是否開源:開源意味着萬一遇到影響業務的bug我們可以通過修改原始碼來修正或者規避問題;
開發語言:開發語言是你擅長的或者有同事擅長的語言則比較容易檢視原始碼、如有bug也可以修改;
社羣活躍度:社羣活躍用的人應該挺多的,這樣前輩們踩過的坑遇到的bug一般都解決了,遇到什麼問題也便於討論;
特性:可靠性、吞吐量、能否搭建叢集;
activeMQ | rabbitMQ | rocketMQ | kafka | |
---|---|---|---|---|
開發語言 | java | erlang | java | Scala和java |
單機吞吐量 | 萬級 | 萬級 | 十萬級 | 十萬級 |
topic數量對吞吐量的影響 | - | - | topic 可以達到幾百/幾千的級別,吞吐量會有較小幅度的下降,這是 RocketMQ 的一大優勢,在同等機器下,可以支撐大量的 topic | topic 從幾十到幾百個時候,吞吐量會大幅度下降,在同等機器下,Kafka 儘量保證 topic 數量不要過多,如果要支撐大規模的 topic,需要增加更多的機器資源 |
時效性 | ms | us級(最低延時) | ms | ms |
可用性 | 高(主從) | 高(主從) | 高 | 高(分佈式) |
訊息可靠性 | 低概率丟失 | 基本不丟 | 理論上不會丟失 | 理論上不會丟失 |
事務 | 支援 | 支援 | 支援 | 支援 |
持久化 | 記憶體、檔案、數據庫 | 記憶體、檔案 | 磁碟檔案 | - |
功能支援 | ||||
總結 | 優點:產品成熟,文件多,支援多種語言;缺點:社羣不活躍,維護少,不支援上千佇列。 | 優點:低延時,支援多種語言,管理介面豐富;缺點:erlang語言較難,叢集不支援擴充套件 | 優點:社羣活躍,阿裡在用,能大量堆積訊息在broker中;缺點:比較依賴阿裡的維護 | 功能較爲簡單,主要支援簡單的 MQ 功能,在大數據領域的實時計算以及日誌採集被大規模使用 |