面試連環炮
- 你用過消息隊列麼?
- 說說你們項目裏是怎麼用消息隊列的?
- 我們有一個訂單系統,訂單系統會每次下一個新訂單的時候,就會發送一條消息到ActiveMQ裏面去,後臺有一個庫存系統,負責獲取消息,然後更新庫存。
- 爲什麼使用消息隊列?
- 你的訂單系統不發送消息到MQ,而是直接調用庫存系統的一個接口,然後直接調用成功了,庫存也更新了,那就不需要使用消息隊列了呀
- 使用消息隊列的主要作用是:異步、解耦、削峯
- 消息隊列都有什麼優缺點?
- Kafka、activeMQ、RibbitMQ、RocketMQ都有什麼優缺點?
- 如何保證消息隊列的高可用?
- 如何保證消息不被重複消費?如何保證消息消費時的冪等性?
- 如何保證消息的可靠性傳輸,要是消息丟失了怎麼辦?
- 如何保證消息的順序性?
- 如何解決消息隊列的延時以及過期失效問題?消息隊列滿了以後該怎麼處理?有幾百萬消息持續積壓幾小時,說說怎麼解決?
- 如果讓你寫一個消息隊列,該如何進行架構設計,說一下你的思路?
解耦
不使用MQ時
A系統發送數據到B、C、D系統,但沒有使用消息隊列時候的耦合場景
當後面系統不斷增加,比如 E,F系統的加入,以及D系統的移除
因爲A系統和其它各種系統耦合起來,那麼需要處理的事情會給出多
使用MQ後
系統A發送一條消息,到消息隊列中,哪個系統需要獲取到哪裏,那麼從MQ中消費數據,如果新系統E加入的話,那麼只需要編寫代碼,然後也直接從MQ中消費即可,當系統D不需要這個數據時,那麼只需要不對該消息進行消費即可。系統A不需要考慮給誰發送數據,也不需要維護這個代碼,不需要考慮人家是否調用成功、失敗、超時等等情況
總結:通過一個MQ,發佈和訂閱模型(Pub/Sub模型),系統A就和其它系統徹底解耦。
需要考慮一下負責的系統中,是否有類似的場景,就是一個系統或者一個模塊,調用了多個系統,互相之間的調用很複雜,維護起來很麻煩。但是其實這個調用是不需要同步調用接口的,如果用MQ給他異步化解耦,也是可以的,這個時候可以考慮在自己的項目中,是不是可以運用這個MQ來進行系統的解耦。
異步
不用MQ的同步高延時請求場景
下面的一個場景就是系統A,調用了其它三個系統的服務,我們發現用戶在執行一個請求後,需要花費很長的時間
我們發現,用戶執行一個接口,就需要花費350毫秒,假設我們將每個接口的耗時增加,可能會將近花費1秒,這個時候一般用戶幾乎不能接受,因爲一般互聯網類的企業,對用戶的直接操作,一般要求是每個請求都必須在200ms以內完成,因爲這個是對用戶是無感知的
使用MQ進行異步化
系統A只需要發送消息到MQ中就直接返回了,然後其它系統各自在MQ中進行消費。用戶在執行系統A的時候,就會感覺非常快就得到響應了。
削峯
沒有用MQ的削峯
一般的MySQL,抗到QPS=2000的時候就已經達到了瓶頸,如果每秒請求達到了5000的話,可能直接就把MySQL打死了。如果MySQL被打死,然後整個系統就崩潰,然後系統就沒法使用。
但是中午的高峯期過了之後,到下午的時候,就成了低峯期,可能也就一萬用戶同時在網站上操作,每秒的請求數量可能就50個請求,對整個系統幾乎沒有任何壓力。
使用MQ來進行削峯
削峯就是大量的請求過來,然後MQ將其消化掉了,然後通過其它系統從MQ中取消息,在逐步進行消費,保證系統的有序運行。一般高峯期不會持續太長,在一段時間後,就會被下游系統消化掉。