注:前提是知道什么是消息隊列。不懂的去搜索各種消息隊列入門(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要全返回才算寫入成功。