😊你好,我是小航,一個正在變禿、變強的文藝傾年。
🔔本專欄《八股消消樂》旨在記錄個人所背的八股文,包括Java/Go開發、Vue開發、系統架構、大模型開發、具身智能、機器學習、深度學習、力扣算法
等相關知識點,期待與你一同探索、學習、進步,一起卷起來叭!
目錄
- 題目
- 答案
- Why use 消息隊列?
- 秒殺場景
- 訂單超時取消
- 事件驅動(Event-Driven)
題目
💬技術棧:RocketMQ、Kafka、RabbitMQ
🔍簡歷內容:熟悉消息隊列常見應用場景,基于事件驅動實現了 SAGA 的分布式事務,保證了事務的低耦合、高擴展、高可用。
🚩面試問:你為什么用 Kafka、RabbitMQ 或 RocketMQ,又或者說你為什么使用某一個中間件?
💡建議暫停思考10s,你有答案了嘛?如果你有不同題解,歡迎評論區留言、打卡。
答案
前置準備:
- 你們公司有沒有使用消息隊列?主要用于解決什么場景的問題?
- 如果使用了消息隊列,那么在具體的場景下不使用消息隊列是否可行?和使用消息隊列的方案比起來,有什么優缺點?
- 你們公司用的是什么消息隊列,它有什么優缺點?
Why use 消息隊列?
為什么要用消息隊列?【其實就是再問在這個業務場景下,不異步、不解耦或者不削峰會有什么問題?】
答案:如果不用消息隊列,性能差、擴展性差、可用性差。【同步調用的缺點】
性能差:業務方必須停下來等待結果,如果我這里需要通知三個下游,那么就需要發起三次調用,并且等它們各自的結果返回之后才能繼續往下執行,或者返回響應,這樣性能太差了。
擴展性差:在使用消息隊列的時候,新的下游要接入,只需要自己去訂閱消息就可以,完全不需要通知任何人。在公司里,可能就是你丟給下游一個文檔,下游自己看看文檔,知道訂閱哪個 topic,消息生產速率有多高,差不多就能自己獨立完成接入了
。
而同步調用的時候,上游必須知道下游的接口,然后要知道如何構造請求、如何解析響應,還要聯調、測試、上線,整個過程都得和下游密切合作,因此效率特別低
,可擴展性很差。
如果在某些場景下確實不能用消息隊列,那么這個擴展性問題可以通過一些技術手段來緩解。比如說上游提供一整套的對接規范,包括 API 定義、請求和響應中每個字段的含義
。這樣下游就對著這個 API 定義來提供實現,上游就不需要適配每一個下游了。
可用性:在同步調用方案中,你必須要確保調用所有的下游都成功了才算是成功了
。所以你還需要額外考慮部分成功部分失敗的問題。
秒殺場景
架構設計:
利用消息隊列把整個秒殺過程分成輕重兩個部分
:
- 進入消息隊列之前:秒殺請求進來之后,會有一個輕量級的服務。這個服務就是
做一些限流、請求校驗和庫存扣減
的事情。這些事情差不多都是內存操作,最多操作 Redis
。當庫存扣減成功之后,就會把秒殺請求丟到一個消息隊列
。 - 進入消息隊列之后:
訂單服務會從消息隊列里面將請求拿出來
,真正創建訂單,并且提示用戶支付
。這一部分就是重量級的操作,無法支撐大規模并發。
訂單超時取消
場景:扣減了庫存之后,用戶沒有支付
怎么辦。
解決方案:如果用戶下單之后一直沒有支付,那么這個訂單就會被取消,從而釋放庫存。想利用消息隊列實現訂單超時取消功能,需要使用 延時消息。(超時時間是 30 分鐘)
延時消息:發送者在發送之后,要過一段時間,消費者才能消費的消息
。
可能引發的并發問題:在 30 分鐘這一個時刻,一邊用戶支付,一邊消費者也消費超時消息,就會有并發問題
。
解決思路:使用分布式鎖、樂觀鎖(在你把訂單更新為超時狀態的時候,需要 確保原始狀態還是未支付。支付那邊也需要確保只有在 status 是未支付的時候才能發起支付。),也可以使用 SELECT FOR UPDATE 鎖住訂單,防止并發操作。
目前主流的消息隊列中 RocketMQ 是支持延時消息的,它有插件支持。但是 Kafka 不支持。
事件驅動(Event-Driven)
事件驅動適合用來解決一些 復雜、步驟繁多、流程冗長 的業務問題。
場景:事件驅動結合 SAGA 分布式事務。
當某一個步驟完成之后,就會發出一個或者多個事件,驅動事務中的后續步驟。包括回滾也是這樣,比如說發出一個代表某一個步驟執行失敗的事件,對應的消費者就會去執行反向補償步驟
。
不過在實時性上要比同步調用差一點
。比如說你有一個分布式事務,就是要求先更新 DB,再更新緩存
。那么在緩存更新失敗的場景下,過程看起來就像圖里展示的這樣。
往期精彩專欄內容,歡迎訂閱:
🔗【八股消消樂】20250622:Elasticsearch查詢優化
🔗【八股消消樂】20250620:Elasticsearch優化—檢索Labubu
🔗【八股消消樂】20250619:構建微服務架構體系—保證服務高可用
🔗【八股消消樂】20250615:構建微服務架構體系—鏈路超時控制
🔗【八股消消樂】20250614:構建微服務架構體系—實現制作庫與線上庫分離
🔗【八股消消樂】20250612:構建微服務架構體系—限流算法優化
🔗【八股消消樂】20250611:構建微服務架構體系—降級策略全總結
🔗【八股消消樂】20250610:構建微服務架構體系—熔斷恢復抖動優化
🔗【八股消消樂】20250609:構建微服務架構體系—負載均衡算法如何優化
🔗【八股消消樂】20250608:構建微服務架構體系—服務注冊與發現
🔗【八股消消樂】20250607:MySQL存儲引擎InnoDB知識點匯總
🔗【八股消消樂】20250606:MySQL參數優化大匯總
🔗【八股消消樂】20250605:端午節產生的消費數據,如何分表分庫?
🔗【八股消消樂】20250604:如何解決SQL線上死鎖事故
🔗【八股消消樂】20250603:索引失效與優化方法總結
🔗【八股消消樂】20250512:慢SQL優化手段總結
🔗【八股消消樂】20250511:項目中如何排查內存持續上升問題
🔗【八股消消樂】20250510:項目中如何優化JVM內存分配?
🔗【八股消消樂】20250509:你在項目中如何優化垃圾回收機制?
🔗【八股消消樂】20250508:Java編譯優化技術在項目中的應用
🔗【八股消消樂】20250507:你了解JVM內存模型嗎?
🔗【八股消消樂】20250506:你是如何設置線程池大小?
🔗【八股消消樂】20250430:十分鐘帶背Duubo中大廠經典面試題
🔗【八股消消樂】20250429:你是如何在項目場景中選取最優并發容器?
🔗【八股消消樂】20250428:你是項目中如何優化多線程上下文切換?
🔗【八股消消樂】20250427:發送請求有遇到服務不可用嗎?如何解決?
📌 [ 筆者 ] 文藝傾年
📃 [ 更新 ] 2025.6.23
? [ 勘誤 ] /* 暫無 */
📜 [ 聲明 ] 由于作者水平有限,本文有錯誤和不準確之處在所難免,本人也很想知道這些錯誤,懇望讀者批評指正!