消息隊列MQ詳解

爲何選擇使用消息隊列

  咱們不會無緣無故引入一個技術棧,必定是看重它的某些特性,畢竟引入一個技術可能存在弊端和風險。咱們在談論爲何使用消息隊列的時候必定要根據具體業務來,好比在實際業務中遇到了什麼困難,若是不使用消息隊列就很棘手,經過使用消息後解決了哪些問題。這裏總結了三點比較核心緣由:解耦、異步、削峯。git

解耦

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

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

  若是使用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 個請求,對整個系統幾乎沒有任何的壓力。blog

  若是使用 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 是業內標準的,絕對沒問題,社區活躍度很高,絕對不會黃,況且幾乎是全世界這個領域的事實性規範。

相關文章
相關標籤/搜索