注:前提是知道什麼是消息隊列。不懂的去搜尋各種消息隊列入門(activeMQ、rabbitMQ、rocketMQ、kafka)
1、為什麼要使用MQ?(MQ的好處:解耦、異步、削峰)
(1)解耦:主要解決系統間的耦合度
場景是系統A會産生使用者ID:userId,要把userId通過調用系統B\C\D的接口傳給他們做業務處理。若添加新系統,也需要此userId,則要再加一個接口調用。耦合嚴重。
解耦的做法就是:在系統A與系統BCD之間,增加消息隊列MQ,系統A産生userId後,将其放入MQ,系統BCD通過監聽MQ,來消費userId。
以上,通過MQ,釋出和訂閱消息的pub/sub模型。
原耦合模型:使用者請求--->A---->BCD; 現解耦模型:使用者請求---->A--->MQ---->BCD;
(2)異步:主要解決請求的耗時
場景是使用者發送請求到系統A,系統A執行完本地SQL(耗時100ms)後,還要調用BCD三個系統的接口,假設三次調用都耗時200ms。那麼,總共一次請求耗時700ms。一旦調用接口變多,耗時會變得更長。
使用MQ解決耗時長的辦法就是,在系統A與系統BCD之間分别增加MQ,系統A将資料消息寫入MQ(耗時5ms),成功就傳回并提示使用者,剩餘的BCD系統自己監聽MQ并做相應業務操作。那麼,這個請求耗時也就是100+5 = 105ms。
模型跟解耦一樣。
(3)削峰:主要解決并發請求百萬級時系統挂了
MYSQL處理能力有限,大概最高2000/秒
場景:某秒殺活動,同一時間大量用請求全怼過來了(100萬請求),不用MQ的話系統就被打死了(資料庫處理不過來了)
模型是: 使用者同時的100萬請求--->系統A----每秒5000個請求---> mysql
使用MQ:将使用者請求先放入MQ,有多少放多少,系統A每次去拿2000個,并請求MySQL資源,系統不會被打死
模型是:使用者100萬請求--->全寫入MQ---> 系統A每次去MQ消費2000條 --->mysql
2、MQ的缺點
(1)系統可用性降低:ABCD四個系統,忽然加一個MQ進來,維護變多,萬一忽然挂了,影響下遊多系統
(2)系統複雜性升高:怎麼保證MQ裡的消息沒有被重複消費?消息丢失了怎麼處理?消息傳遞的順序性怎麼保證?
(3)一緻性問題:異步裡面,A處理完直接傳回成功了,但是最後一個系統D寫入失敗了,咋整
3、activeMQ、rabbitMQ、rocketMQ、kafka的差別
4、如何設計一個MQ,架構如何設計?
彙總幾個解決的MQ的線上問題來回答
(1)支援可伸縮性。即需要的時候快速擴容,增加吞吐量和容量,參考kafka的分布式系統
(2)MQ的資料要不要落磁盤?肯定要,保證資料在異常情況下不丢。落的時候順序寫入(kafka的思路)
(3)MQ的高可用性。參考kafka,多副本及leader--follower挂了重新選舉的機制
(4)支援資料0丢失。參考kafka資料丢失的解決方案,消費端手動送出offset,kafka端設定參數保證副本個數、及ack要全傳回才算寫入成功。