天天看點

為什麼使用消息隊列?消息隊列有什麼優點和缺點?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼優點和缺點? - 米兜Java

為什麼使用消息隊列?消息隊列有什麼優點和缺點?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼優點和缺點?

面試題

  • 為什麼使用消息隊列?
  • 消息隊列有什麼優點和缺點?
  • Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼差別,以及适合哪些場景?

面試官心理分析

其實面試官主要是想看看:

  • 第一,你知不知道你們系統裡為什麼要用消息隊列這個東西?

    不少候選人,說自己項目裡用了 Redis、MQ,但是其實他并不知道自己為什麼要用這個東西。其實說白了,就是為了用而用,或者是别人設計的架構,他從頭到尾都沒思考過。

    沒有對自己的架構問過為什麼的人,一定是平時沒有思考的人,面試官對這類候選人印象通常很不好。因為面試官擔心你進了團隊之後隻會木頭木腦的幹呆活兒,不會自己思考。

  • 第二,你既然用了消息隊列這個東西,你知不知道用了有什麼好處&壞處?

    你要是沒考慮過這個,那你盲目弄個 MQ 進系統裡,後面出了問題你是不是就自己溜了給公司留坑?你要是沒考慮過引入一個技術可能存在的弊端和風險,面試官把這類候選人招進來了,基本可能就是挖坑型選手。就怕你幹 1 年挖一堆坑,自己跳槽了,給公司留下無窮後患。

  • 第三,既然你用了 MQ,可能是某一種 MQ,那麼你當時做沒做過調研?

    你别傻乎乎的自己拍腦袋看個人喜好就瞎用了一個 MQ,比如 Kafka,甚至都從沒調研過業界流行的 MQ 到底有哪幾種。每一個 MQ 的優點和缺點是什麼。每一個 MQ 沒有絕對的好壞,但是就是看用在哪個場景可以揚長避短,利用其優勢,規避其劣勢。

    如果是一個不考慮技術選型的候選人招進了團隊,leader 交給他一個任務,去設計個什麼系統,他在裡面用一些技術,可能都沒考慮過選型,最後選的技術可能并不一定合适,一樣是留坑。

面試題剖析

為什麼使用消息隊列

其實就是問問你消息隊列都有哪些使用場景,然後你項目裡具體是什麼場景,說說你在這個場景裡用消息隊列是什麼?

面試官問你這個問題,期望的一個回答是說,你們公司有個什麼業務場景,這個業務場景有個什麼技術挑戰,如果不用 MQ 可能會很麻煩,但是你現在用了 MQ 之後帶給了你很多的好處。

先說一下消息隊列常見的使用場景吧,其實場景有很多,但是比較核心的有 3 個:解耦、異步、削峰。

解耦

看這麼個場景。A 系統發送資料到 BCD 三個系統,通過接口調用發送。如果 E 系統也要這個資料呢?那如果 C 系統現在不需要了呢?A 系統負責人幾乎崩潰......

為什麼使用消息隊列?消息隊列有什麼優點和缺點?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼優點和缺點? - 米兜Java

在這個場景中,A 系統跟其它各種亂七八糟的系統嚴重耦合,A 系統産生一條比較關鍵的資料,很多系統都需要 A 系統将這個資料發送過來。A 系統要時時刻刻考慮 BCDE 四個系統如果挂了該咋辦?要不要重發,要不要把消息存起來?頭發都白了啊!

如果使用 MQ,A 系統産生一條資料,發送到 MQ 裡面去,哪個系統需要資料自己去 MQ 裡面消費。如果新系統需要資料,直接從 MQ 裡消費即可;如果某個系統不需要這條資料了,就取消對 MQ 消息的消費即可。這樣下來,A 系統壓根兒不需要去考慮要給誰發送資料,不需要維護這個代碼,也不需要考慮人家是否調用成功、失敗逾時等情況。

為什麼使用消息隊列?消息隊列有什麼優點和缺點?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼優點和缺點? - 米兜Java

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

面試技巧:你需要去考慮一下你負責的系統中是否有類似的場景,就是一個系統或者一個子產品,調用了多個系統或者子產品,互相之間的調用很複雜,維護起來很麻煩。但是其實這個調用是不需要直接同步調用接口的,如果用 MQ 給它異步化解耦,也是可以的,你就需要去考慮在你的項目裡,是不是可以運用這個 MQ 去進行系統的解耦。在履歷中展現出來這塊東西,用 MQ 作解耦。

異步

再來看一個場景,A 系統接收一個請求,需要在自己本地寫庫,還需要在 BCD 三個系統寫庫,自己本地寫庫要 3ms,BCD 三個系統分别寫庫要 300ms、450ms、200ms。最終請求總延時是 3 + 300 + 450 + 200 = 953ms,接近 1s,使用者感覺搞個什麼東西,慢死了慢死了。使用者通過浏覽器發起請求,等待個 1s,這幾乎是不可接受的。

為什麼使用消息隊列?消息隊列有什麼優點和缺點?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼優點和缺點? - 米兜Java

一般網際網路類的企業,對于使用者直接的操作,一般要求是每個請求都必須在 200 ms 以内完成,對使用者幾乎是無感覺的。

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

為什麼使用消息隊列?消息隊列有什麼優點和缺點?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼優點和缺點? - 米兜Java

削峰

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

一般的 MySQL,扛到每秒 2k 個請求就差不多了,如果每秒請求到 5k 的話,可能就直接把 MySQL 給打死了,導緻系統崩潰,使用者也就沒法再使用系統了。

但是高峰期一過,到了下午的時候,就成了低峰期,可能也就 1w 的使用者同時在網站上操作,每秒中的請求數量可能也就 50 個請求,對整個系統幾乎沒有任何的壓力。

為什麼使用消息隊列?消息隊列有什麼優點和缺點?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼優點和缺點? - 米兜Java

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

為什麼使用消息隊列?消息隊列有什麼優點和缺點?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼優點和缺點? - 米兜Java

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

消息隊列有什麼優缺點

優點上面已經說了,就是在特殊場景下有其對應的好處,解耦、異步、削峰。

缺點有以下幾個:

  • 系統可用性降低

    系統引入的外部依賴越多,越容易挂掉。本來你就是 A 系統調用 BCD 三個系統的接口就好了,人 ABCD 四個系統好好的,沒啥問題,你偏加個 MQ 進來,萬一 MQ 挂了咋整,MQ 一挂,整套系統崩潰的,你不就完了?如何保證消息隊列的高可用,可以點選這裡檢視。

  • 系統複雜度提高

    硬生生加個 MQ 進來,你怎麼保證消息沒有重複消費?怎麼處理消息丢失的情況?怎麼保證消息傳遞的順序性?頭大頭大,問題一大堆,痛苦不已。

  • 一緻性問題

    A 系統處理完了直接傳回成功了,人都以為你這個請求就成功了;但是問題是,要是 BCD 三個系統那裡,BD 兩個系統寫庫成功了,結果 C 系統寫庫失敗了,咋整?你這資料就不一緻了。

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

Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什麼優缺點?

特性 ActiveMQ RabbitMQ RocketMQ Kafka
單機吞吐量 萬級,比 RocketMQ、Kafka 低一個數量級 同 ActiveMQ 10 萬級,支撐高吞吐 10 萬級,高吞吐,一般配合大資料類的系統來進行實時資料計算、日志采集等場景
topic 數量對吞吐量的影響 topic 可以達到幾百/幾千的級别,吞吐量會有較小幅度的下降,這是 RocketMQ 的一大優勢,在同等機器下,可以支撐大量的 topic topic 從幾十到幾百個時候,吞吐量會大幅度下降,在同等機器下,Kafka 盡量保證 topic 數量不要過多,如果要支撐大規模的 topic,需要增加更多的機器資源
時效性 ms 級 微秒級,這是 RabbitMQ 的一大特點,延遲最低 ms 級 延遲在 ms 級以内
可用性 高,基于主從架構實作高可用 同 ActiveMQ 非常高,分布式架構 非常高,分布式,一個資料多個副本,少數機器當機,不會丢失資料,不會導緻不可用
消息可靠性 有較低的機率丢失資料 基本不丢 經過參數優化配置,可以做到 0 丢失 同 RocketMQ
功能支援 MQ 領域的功能極其完備 基于 erlang 開發,并發能力很強,性能極好,延時很低 MQ 功能較為完善,還是分布式的,擴充性好 功能較為簡單,主要支援簡單的 MQ 功能,在大資料領域的實時計算以及日志采集被大規模使用

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

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

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

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

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

如果是大資料領域的實時計算、日志采集等場景,用 Kafka 是業内标準的,絕對沒問題,社群活躍度很高,絕對不會黃,何況幾乎是全世界這個領域的事實性規範。

本文在米兜公衆号連結:

https://mp.weixin.qq.com/s/G24Upe0lSQhWVC8XQ5c1rA

歡迎關注米兜Java,一個注在共享、交流的Java學習平台。

發表于

2019-09-08 22:35 

米兜Java 

閱讀(2874) 

評論(5) 

編輯 

收藏 

舉報