1. 引子
訊息佇列分布式系統中重要的組件,一種存放訊息的容器,主要作用有解耦、異步、削鋒,是大型分布式系統不可缺少的中間件,
常見的訊息佇列有 ActiveMQ,RabbitMQ,RocketMQ,Kafka,
簡歷中涉及到了訊息佇列,面試官先問了這樣幾個問題:
- 你們系統里為什么要使用訊息佇列?
- 既然使用了訊息佇列,說說他還有什么使用場景?
- 訊息佇列的優缺點是什么?
2. 為什么使用訊息佇列?
我的回答:甲方提供 EOS 充值服務,我方進行呼叫,出于解耦的目的,引入了訊息佇列,
一個類似應試的回答方法,就是思考面試官問這個問題是出于什么目的,想獲得的是什么樣的答案?
當問到為什么使用訊息佇列時,面試官期望的回答是公司的 xxx 業務遇到了挑戰,不用 MQ 會有麻煩,使用 MQ 之后帶來了好處,
通過一個問題就能看出是為了用而用,還是經過思考之后使用,
3. 訊息佇列的使用場景?
問訊息佇列的使用場景,和問訊息佇列有什么優點,訊息佇列有什么作用是等價的,
訊息佇列的作用主要有三個解耦、異步、削峰,
解耦

B,C,D 系統需要使用 A 系統產生的關鍵資料,
- 無訊息佇列時
- 系統 A 為系統 B、C、D 等提供各自的介面,導致系統 A 與它們緊密耦合
- 添加系統 E 又需要介面,洗掉 B 系統原介面又沒用了
- 有訊息佇列時
- 系統 A 作為生產者,將訊息發送到訊息佇列
- 系統 B、C、D 作為消費者訂閱訊息
- 新增消費者只需訂閱訊息,對原系統和業務沒有影響
異步

用戶請求資料時,系統的回應時間是保證用戶體驗很重要的一部分,
- 無訊息佇列時
- 用戶請求 A 系統,A 系統需要等待 BCD 執行完成之后回應
- 用戶收到回應用時近 1 秒
- 用訊息佇列時
- 用戶請求 A 系統,A 系統將請求推到訊息佇列中,B、C、D 異步執行
- 用戶收到回應用時 200 毫秒
削峰

秒殺場景下,每秒有 5000 個請求,Mysql 每秒最大處理 2000 條 sql,
- 無訊息佇列時
- 用戶請求資料直接寫入資料庫,高并發時資料庫壓力劇增,甚至奔潰
- Mysql 宕機,整個系統都不能用了
- 有訊息佇列時系統 B、C、D
- 用戶請求資料先存入 MQ 中
- 系統 A 每秒讀取 2000 條資料進行處理
- 每秒多出 3000 條未處理資料按場景稍后處理
4. 訊息佇列有什么缺點?
優點前面已經說過了,還需要討論一下缺點,
為什么要問缺點是什么?
凡事都有兩面性,如果只是考慮到訊息佇列的優點,而沒有考慮缺點,這就是一個潘多拉的魔盒,打開魔盒,接踵而來的會是一系列的意外,
推廣到引入其他技術亦然,只有考慮到缺點之后才可以采取額外的技術方案或者架構來規避這些缺點,
系統可用性降低
- 系統引入的外部依賴越多,宕機的可能性就越大
- 系統引入訊息佇列,就要考慮訊息佇列的可靠性
- 比如原本只需要考慮 A,B,C,D 四個系統
- 引入訊息佇列之后就需要考慮 A,B,C,D 四個系統外加訊息佇列
系統復雜度提高
- 訊息重復消費問題
- 訊息丟失問題
- 訊息傳遞順序問題
一致性問題
- A 系統處理完回傳成功,即認為請求成功
- 但是也存在 BC 系統寫入成功,而 D 系統寫入失敗的情況
- 這樣的情況就是資料不一致
總結
面試官問到 MQ 的時候,希望考察我們在使用 MQ 的時候是否有過自己的思考,沒有完美的技術,任何技術都具有兩面性,要考慮它的使用場景,并且對可能遇到的風險做到心中有數,提前預防,

思考
引入訊息佇列之后:
- 如何保證高可用?
- 如何避免訊息的重復消費和訊息丟失?
- 如何保證訊息的順序執行?
下一篇文章一起討論,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/5996.html
標籤:架構設計
