消息隊列MQ詳解


為什么選擇使用消息隊列

  我們不會平白無故引入一個技術棧,一定是看重它的某些特性,畢竟引入一個技術可能存在弊端和風險。我們在談論為什么使用消息隊列的時候一定要根據具體業務來,比如在實際業務中遇到了什么困難,如果不使用消息隊列就很棘手,通過使用消息后解決了哪些問題。這里總結了三點比較核心原因:解耦、異步、削峰。

解耦

  在某個場景下,A系統需要向BCD系統通過接口調用發送一條數據過去,這個時候E系統也要數據,D系統也要數據,此時A系統內心肯定是崩潰的。

  上訴場景中A系統和其他系統耦合性很高,每當產生一條數據的時候A系統都要考慮到其他系統是否在線?是否掛掉?是否接收正常?所以A系統真的是太難了!

  如果使用MQ,A系統產生一條數據后就放進MQ,其他系統需要就自己到MQ系統中去消費,不需要就可以取消對該消息的訂閱,A系統壓根不需要再考慮給其他系統發送數據的各種亂七八糟問題。

  總結:通過一個 MQ,Pub/Sub 發布訂閱消息這么一個模型,A 系統就跟其它系統徹底解耦了。

異步

  在某場景下,A系統收到一條數據后需要在自己本地寫庫,同時還要在BCD三個系統寫庫,自己本地寫庫要 3ms,BCD 三個系統分別寫庫要 300ms、450ms、200ms。總共要延時3 + 300 + 450 + 200 = 953ms,接近 1s啊,對強迫症的人來說簡直要爆炸!

  正常一個請求控制在200ms左右,客戶是沒有感知的。

  如果使用 MQ,那么 A 系統連續發送 3 條消息到 MQ 隊列中,假如耗時 5ms,A 系統從接受一個請求到返回響應給用戶,總時長是 3 + 5 = 8ms,對於用戶而言,其實感覺上就是點個按鈕,8ms 以后就直接返回了,爽!網站做得真好,真快!美滋滋!

削峰

每天 0:00 到 12:00,A 系統風平浪靜,每秒並發請求數量就 50 個。結果每次一到 12:00 ~ 13:00 ,每秒並發請求數量突然會暴增到 5k+ 條。但是系統是直接基於 MySQL 的,大量的請求涌入 MySQL,每秒鍾對 MySQL 執行約 5k 條 SQL。

  一般的 MySQL,扛到每秒 2k 個請求就差不多了,如果每秒請求到 5k 的話,可能就直接把 MySQL 給打死了,導致系統崩潰,用戶也就沒法再使用系統了。但是高峰期一過,到了下午的時候,就成了低峰期,可能也就 1w 的用戶同時在網站上操作,每秒中的請求數量可能也就 50 個請求,對整個系統幾乎沒有任何的壓力。

  如果使用 MQ,每秒 5k 個請求寫入 MQ,A 系統每秒鍾最多處理 2k 個請求,因為 MySQL 每秒鍾最多處理 2k 個。A 系統從 MQ 中慢慢拉取請求,每秒鍾就拉取 2k 個請求,不要超過自己每秒能處理的最大請求數量就 ok,這樣下來,哪怕是高峰期的時候,A 系統也絕對不會掛掉。而 MQ 每秒鍾 5k 個請求進來,就 2k 個請求出去,結果就導致在中午高峰期(1 個小時),可能有幾十萬甚至幾百萬的請求積壓在 MQ 中。

  這個短暫的高峰期積壓是 ok 的,因為高峰期過了之后,每秒鍾就 50 個請求進 MQ,但是 A 系統依然會按照每秒 2k 個請求的速度在處理。所以說,只要高峰期一過,A 系統就會快速將積壓的消息給解決掉。

消息隊列的缺點

  上面吹了消息隊列的一堆優點,但是也不能不知道使用它帶來的一些缺點吧!缺點有以下幾點:

  • 系統可用性降低
    系統引入的外部依賴越多,越容易掛掉。本來你就是 A 系統調用 BCD 三個系統的接口就好了,人 ABCD 四個系統好好的,沒啥問題,你偏加個 MQ 進來,萬一 MQ 掛了咋整,MQ 一掛,整套系統崩潰的,你不就完了?

  • 系統復雜度提高
    硬生生加個 MQ 進來,你怎么保證消息沒有重復消費?怎么處理消息丟失情況?怎么保證消息傳遞的順序性?頭大頭大,問題一大堆,痛苦不已。

  • 一致性問題
    A 系統處理完了直接返回成功了,人都以為你這個請求就成功了;但是問題是,要是 BCD 三個系統那里,BD 兩個系統寫庫成功了,結果 C 系統寫庫失敗了,咋整?你這數據就不一致了。

  所以消息隊列實際是一種非常復雜的架構,你引入它有很多好處,但是也得針對它帶來的壞處做各種額外的技術方案和架構來規避掉,做好之后,你會發現,媽呀,系統復雜度提升了一個數量級,也許是復雜了 10 倍。但是關鍵時刻,用,還是得用的。

幾個消息隊列的比較

綜上,各種對比之后,有如下建議:

一般的業務系統要引入 MQ,最早大家都用 ActiveMQ,但是現在確實大家用的不多了,沒經過大規模吞吐量場景的驗證,社區也不是很活躍,所以大家還是算了吧,我個人不推薦用這個了;

后來大家開始用 RabbitMQ,但是確實 erlang 語言阻止了大量的 Java 工程師去深入研究和掌控它,對公司而言,幾乎處於不可控的狀態,但是確實人家是開源的,比較穩定的支持,活躍度也高;

不過現在確實越來越多的公司會去用 RocketMQ,確實很不錯,畢竟是阿里出品,但社區可能有突然黃掉的風險(目前 RocketMQ 已捐給 Apache,但 GitHub 上的活躍度其實不算高)對自己公司技術實力有絕對自信的,推薦用 RocketMQ,否則回去老老實實用 RabbitMQ 吧,人家有活躍的開源社區,絕對不會黃。

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

如果是大數據領域的實時計算、日志采集等場景,用 Kafka 是業內標准的,絕對沒問題,社區活躍度很高,絕對不會黃,何況幾乎是全世界這個領域的事實性規范。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM