1. 程式人生 > >訊息佇列MQ分析

訊息佇列MQ分析

做java開發的面試基本會遇到java基礎知識,設計模式,多執行緒,io,集合等,spring/springMvc/mybatis/springBoot,mysql/oracle/sql優化這些。現在僅僅會這些是不夠的,還會要求快取、訊息佇列、訊息中介軟體。springCloud/Dubbo等分散式架構。。。等等,好多的同學可能沒搞過那些東西,或者之前自己看過一些,知道點demo和概念,略知一二,就是面試的時候容易被面試官幾個連環炮打蒙,然後面試就掛了,所以我們需要集中分析一下這些技術。這裡我們先來分析一下訊息佇列。

我們先提出幾個問題:

  • 為什麼使用訊息佇列啊?
  • 用訊息佇列都有什麼優點和缺點?
  • kafka、activemq、rabbitmq、rocketmq都有什麼區別?
  • 如何保證訊息佇列的高可用啊?
  • 如何保證訊息不被重複消費啊?如何保證消費的時候是冪等的啊?
  • 如何保證訊息的可靠性傳輸啊?要是訊息丟失了怎麼辦啊?
  • 那如何保證訊息的順序性?
  • 如何解決訊息佇列的延時以及過期失效問題?訊息佇列滿了以後該怎麼處理?有幾百萬訊息持續積壓幾小時,怎麼解決?
  • 如果讓你寫一個訊息佇列,該如何進行架構設計啊?

訊息佇列比較核心的有3個:解耦、非同步、削峰
解耦:現場畫個圖來說明一下,A系統傳送個數據到BCD三個系統,介面呼叫傳送,那如果E系統也要這個資料呢?那如果C系統現在不需要了呢?現在A系統又要傳送第二種資料了呢?A系統負責人瀕臨崩潰中。。。再來點更加崩潰的事兒,A系統要時時刻刻考慮BCDE四個系統如果掛了咋辦?我要不要重發?我要不要把訊息存起來?頭髮都白了啊。。。
不用解耦的時候:
在這裡插入圖片描述


使用訊息佇列的情況:
在這裡插入圖片描述
以上就是解耦的效果,相信大家都能理解,接下來我們來看看
非同步:現場畫個圖來說明一下,A系統接收一個請求,需要在自己本地寫庫,還需要在BCD三個系統寫庫,自己本地寫庫要3ms,BCD三個系統分別寫庫要300ms、450ms、200ms。最終請求總延時是3 + 300 + 450 + 200 = 953ms,接近1s,使用者感覺搞個什麼東西,慢死了慢死了。
一般的情況:
在這裡插入圖片描述

使用訊息佇列後的情況:
在這裡插入圖片描述
通過比較我們可以清楚的感覺到兩種情況的差異。

削峰:每天0點到11點,A系統風平浪靜,每秒併發請求數量就100個。結果每次一到11點~1點,每秒併發請求數量突然會暴增到1萬條。但是系統最大的處理能力就只能是每秒鐘處理1000個請求啊。。。尷尬了,系統會死。。。
在這裡插入圖片描述


使用MQ以後的情況:
在這裡插入圖片描述

優點上面已經說了,就是在特殊場景下有其對應的好處,解耦、非同步、削峰

缺點呢?顯而易見的

  1. 系統可用性降低:系統引入的外部依賴越多,越容易掛掉,本來你就是A系統呼叫BCD三個系統的介面就好了,人ABCD四個系統好好的,沒啥問題,你偏加個MQ進來,萬一MQ掛了咋整?MQ掛了,整套系統崩潰了,你不就完了麼。
  2. 系統複雜性提高:硬生生加個MQ進來,你怎麼保證訊息沒有重複消費?怎麼處理訊息丟失的情況?怎麼保證訊息傳遞的順序性?頭大頭大,問題一大堆,痛苦不已
  3. 一致性問題:A系統處理完了直接返回成功了,人都以為你這個請求就成功了;但是問題是,要是BCD三個系統那裡,BD兩個系統寫庫成功了,結果C系統寫庫失敗了,咋整?你這資料就不一致了。

所以訊息佇列實際是一種非常複雜的架構,你引入它有很多好處,但是也得針對它帶來的壞處做各種額外的技術方案和架構來規避掉,最好之後,你會發現,媽呀,系統複雜度提升了一個數量級,也許是複雜了10倍。但是關鍵時刻,用,還是得用的。。。

在這裡插入圖片描述

kafka、activemq、rabbitmq、rocketmq都有什麼優點和缺點啊?
通過分析我得出以下結論:

  • 所以中小型公司,技術實力較為一般,技術挑戰不是特別高,用RabbitMQ是不錯的選擇;
  • 大型公司,基礎架構研發實力較強,用RocketMQ是很好的選擇;
  • 如果是大資料領域的實時計算、日誌採集等場景,用Kafka是業內標準的,絕對沒問題。