幾種mq的對比


mq的優點

解耦、異步、削峰

場景1

在這個場景中,A 系統跟其它各種亂七八糟的系統嚴重耦合,A 系統產生一條比較關鍵的數據,很多系統都需要 A 系統將這個數據發送過來。A 系統要時時刻刻考慮 BCDE 四個系統如果掛了該咋辦?要不要重發,要不要把消息存起來?頭發都白了啊!

如果使用 MQ,A 系統產生一條數據,發送到 MQ 里面去,哪個系統需要數據自己去 MQ 里面消費。如果新系統需要數據,直接從 MQ 里消費即可;如果某個系統不需要這條數據了,就取消對 MQ 消息的消費即可。這樣下來,A 系統壓根兒不需要去考慮要給誰發送數據,不需要維護這個代碼,也不需要考慮人家是否調用成功、失敗超時等情況。

 

場景2

總結:通過一個 MQ,Pub/Sub 發布訂閱消息這么一個模型,A 系統就跟其它系統徹底解耦了。

面試技巧:你需要去考慮一下你負責的系統中是否有類似的場景,就是一個系統或者一個模塊,調用了多個系統或者模塊,互相之間的調用很復雜,維護起來很麻煩。但是其實這個調用是不需要直接同步調用接口的,如果用 MQ 給它異步化解耦,也是可以的,你就需要去考慮在你的項目里,是不是可以運用這個 MQ 去進行系統的解耦。在簡歷中體現出來這塊東西,用 MQ 作解耦。
異步

再來看一個場景,A 系統接收一個請求,需要在自己本地寫庫,還需要在 BCD 三個系統寫庫,自己本地寫庫要 3ms,BCD 三個系統分別寫庫要 300ms、450ms、200ms。最終請求總延時是 3 + 300 + 450 + 200 = 953ms,接近 1s,用戶感覺搞個什么東西,慢死了慢死了。用戶通過瀏覽器發起請求,等待個 1s,這幾乎是不可接受的。

 

場景3

每天 0:00 到 12:00,A 系統風平浪靜,每秒並發請求數量就 50 個。結果每次一到 12:00 ~ 13:00 ,每秒並發請求數量突然會暴增到 5k+ 條。但是系統是直接基於 MySQL 的,大量的請求涌入 MySQL,每秒鍾對 MySQL 執行約 5k 條 SQL。

一般的 MySQL,扛到每秒 2k 個請求就差不多了,如果每秒請求到 5k 的話,可能就直接把 MySQL 給打死了,導致系統崩潰,用戶也就沒法再使用系統了。

但是高峰期一過,到了下午的時候,就成了低峰期,可能也就 1w 的用戶同時在網站上操作,每秒中的請求數量可能也就 50 個請求,對整個系統幾乎沒有任何的壓力。

 

如果使用 MQ,每秒 5k 個請求寫入 MQ,A 系統每秒鍾最多處理 2k 個請求,因為 MySQL 每秒鍾最多處理 2k 個。A 系統從 MQ 中慢慢拉取請求,每秒鍾就拉取 2k 個請求,不要超過自己每秒能處理的最大請求數量就 ok,這樣下來,哪怕是高峰期的時候,A 系統也絕對不會掛掉。而 MQ 每秒鍾 5k 個請求進來,就 2k 個請求出去,結果就導致在中午高峰期(1 個小時),可能有幾十萬甚至幾百萬的請求積壓在 MQ 中。

這個短暫的高峰期積壓是 ok 的,因為高峰期過了之后,每秒鍾就 50 個請求進 MQ,但是 A 系統依然會按照每秒 2k 個請求的速度在處理。所以說,只要高峰期一過,A 系統就會快速將積壓的消息給解決掉。

幾種mq的對比情況

 

mq常見問題

怎么保證消息沒有重復消費

1.如果是拿這個消息做數據庫insert操作(事實上update和delete重復也不影響)給這個消息做一個唯一主鍵,那么就算出現重復消費的情況,就會導致主鍵沖突,避免數據庫出現臟數據。
2.當拿到這個消息做redis的set的操作,那就容易了,不用解決,因為你無論set幾次結果都是一樣的,set操作本來就算冪等操作。
3.如果上面兩種情況還不行,准備一個第三方存儲,來做消費記錄。以redis為例,給消息分配一個全局id,只要消費過該消息,將<id,message>以K-V形式寫入redis。那消費者開始消費前,先去redis中查詢有沒消費記錄即可。

 

怎么處理消息丟失的情況(RocketMq的舉例)

1.要保證消息不丟失,首先需要將os cache的異步刷盤策略改為同步刷盤,

2.RocketMQ在消費者中注冊了一個監聽器,當消費者獲取到了消息,就會去回調這個監聽器函數,去處理里面的消息當你的消息處理完畢之后,才會返回ConsumeConcurrentlyStatus.CONSUME_SUCCESS
只有返回了CONSUME_SUCCESS,消費者才會告訴RocketMQ我已經消費完了,此時如果消費者宕機,消息已經處理完了,也就不會丟失消息了

 


怎么保證消息傳遞的順序性(RocketMq的舉例)

RocketMq的順序消息


怎么保證多系統消息一致性

設計三個系統,支持失敗重傳,例如:“支付系統-MQ服務-用戶余額系統”**三者的處理滿足數據的一致性要求。例如,如果支付系統感知到消息發送失敗后還可以進行重新投遞,從而確保支付系統與用戶余額數據的最終一致性。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM