高併發架構消息隊列面試題解析

 

面試題面試

  • 爲何使用消息隊列?瀏覽器

  • 消息隊列有什麼優勢和缺點?架構

  • Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼區別,以及適合哪些場景?併發

 

面試官心理分析機器學習

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

  • 第一,你知不知道大家系統裏爲何要用消息隊列這個東西? 很多候選人,說本身項目裏用了 Redis、MQ,可是其實他並不知道本身爲何要用這個東西。其實說白了,就是爲了用而用,或者是別人設計的架構,他從頭至尾都沒思考過。 沒有對本身的架構問過爲何的人,必定是平時沒有思考的人,面試官對這類候選人印象一般很很差。由於面試官擔憂你進了團隊以後只會木頭木腦的幹呆活兒,不會本身思考。分佈式

 

  • 第二,你既然用了消息隊列這個東西,你知不知道用了有什麼好處&壞處? 你要是沒考慮過這個,那你盲目弄個 MQ 進系統裏,後面出了問題你是否是就本身溜了給公司留坑?你要是沒考慮過引入一個技術可能存在的弊端和風險,面試官把這類候選人招進來了,基本可能就是挖坑型選手。就怕你幹 1 年挖一堆坑,本身跳槽了,給公司留下無窮後患。高併發

 

  • 第三,既然你用了 MQ,多是某一種 MQ,那麼你當時作沒作過調研? 你別傻乎乎的本身拍腦殼看我的喜愛就瞎用了一個 MQ,好比 Kafka,甚至都從沒調研過業界流行的 MQ 到底有哪幾種。每個 MQ 的優勢和缺點是什麼。每個 MQ 沒有絕對的好壞,可是就是看用在哪一個場景能夠揚長避短,利用其優點,規避其劣勢。 若是是一個不考慮技術選型的候選人招進了團隊,leader 交給他一個任務,去設計個什麼系統,他在裏面用一些技術,可能都沒考慮過選型,最後選的技術可能並不必定合適,同樣是留坑。oop

 

面試題剖析學習

 

爲何使用消息隊列

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

面試官問你這個問題,指望的一個回答是說,大家公司有個什麼業務場景,這個業務場景有個什麼技術挑戰,若是不用 MQ 可能會很麻煩,可是你如今用了 MQ 以後帶給了你不少的好處。

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

 

解耦

看這麼個場景。A 系統發送數據到 BCD 三個系統,經過接口調用發送。若是 E 系統也要這個數據呢?那若是 C 系統如今不須要了呢?A 系統負責人幾乎崩潰......

 

 

在這個場景中,A 系統跟其它各類亂七八糟的系統嚴重耦合,A 系統產生一條比較關鍵的數據,不少系統都須要 A 系統將這個數據發送過來。A 系統要時時刻刻考慮 BCDE 四個系統若是掛了該咋辦?要不要重發,要不要把消息存起來?頭髮都白了啊!

若是使用 MQ,A 系統產生一條數據,發送到 MQ 裏面去,哪一個系統須要數據本身去 MQ 裏面消費。若是新系統須要數據,直接從 MQ 裏消費便可;若是某個系統不須要這條數據了,就取消對 MQ 消息的消費便可。這樣下來,A 系統壓根兒不須要去考慮要給誰發送數據,不須要維護這個代碼,也不須要考慮人家是否調用成功、失敗超時等狀況。

 

 

總結:經過一個 MQ,Pub/Sub 發佈訂閱消息這麼一個模型,A 系統就跟其它系統完全解耦了。

面試技巧:你須要去考慮一下你負責的系統中是否有相似的場景,就是一個系統或者一個模塊,調用了多個系統或者模塊,互相之間的調用很複雜,維護起來很麻煩。可是其實這個調用是不須要直接同步調用接口的,若是用 MQ 給它異步化解耦,也是能夠的,你就須要去考慮在你的項目裏,是否是能夠運用這個 MQ 去進行系統的解耦。在簡歷中體現出來這塊東西,用 MQ 做解耦。

 

異步

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

 

 

通常互聯網類的企業,對於用戶直接的操做,通常要求是每一個請求都必須在 200 ms 之內完成,對用戶幾乎是無感知的。

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

 

免費Java資料須要本身領取,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo/Kafka、Hadoop、Hbase、Flink等高併發分佈式、大數據、機器學習等技術。 傳送門:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q

相關文章
相關標籤/搜索