01 MQ作用、種類、選型

2020-08-10 13:49:48

爲什麼要使用訊息佇列?訊息佇列的好處?用途?

訊息佇列用來解決系統之間的通訊問題,主要功能就是收發訊息,使用訊息佇列有幾個好處:

  1. 解耦:減少了系統之間的依賴關係,如果在一個系統A中直接呼叫另一個系統B的介面,如果B執行失敗,A也會執行失敗,兩個系統高度耦合,不利於程式碼的擴充套件和維護。
  2. 非同步:提高系統響應速度,減少使用者的等待時間。舉例:假設我現在有一個下單功能,它包含了鎖定庫存,訂單入庫,給使用者發簡訊3個操作,需要等這3個操作完成後才能 纔能給使用者返回結果,使用者需要等待較長的時間。我可以這樣優化,在我這個下單功能中決定下單是否成功的操作是鎖定庫存,等鎖定庫存操作完成後就立刻返回結果給使用者,然後將請求的數據放到訊息佇列中,由訊息佇列非同步進行後續2步操作。好處是減少了使用者等待的時間,充分利用了伺服器的資源在短時間內處理了更多的請求。
  3. 削峯限流:比如說秒殺系統秒殺時一秒鐘有5000併發量,但是伺服器每秒鐘只能請求1000併發量,那多出來的4000個請求,可能會使系統崩潰,解決辦法是把多出來的請求到訊息佇列裡中,秒殺系統根據自己能夠處理的請求數去訊息對佇列裡拿數據。這樣系統就不會崩潰。缺點是增加了系統呼叫鏈環節,導致總體響應時延變長。另外上下遊系統需要將同步呼叫改爲非同步訊息,增加了系統的複雜度。

使用訊息佇列有什麼缺點?

  1. 訊息佇列時延問題
  2. 降低系統的可用性:系統引入的外部依賴越多,越容易掛掉。
  3. 系統複雜度提高:使用 MQ 後可能需要保證訊息沒有被重複消費、訊息沒有丟失、保證訊息傳遞的順序性 等問題;
  4. 一致性問題:A 系統處理完直接返回成功了,通過訊息佇列通知BCD執行,而且 B 和 D 兩個系統也寫庫成功了,但 C 系統寫庫失敗了,就造成數據不一致了。

你還了解哪些訊息佇列?

  • ActiveMQ:早期用的比較多,現在基本上沒什麼人用,社羣也不是很活躍。吞吐量是萬級,時延ms級別,有較低的概率會丟失訊息。
  • RabbitMQ:使用簡單,開箱即用。效能也很好,社羣活躍度高,吞吐量萬級,是用erlang語言開發的,對於java開發者來說很難看懂,所以很難做擴充套件和二次開發,對於訊息堆積的支援不是很好,訊息堆積時,效能會急劇下降。如果對效能要求不高,用RabbitMQ即可。
  • RocketMQ:吞吐量很高,達到了幾十萬級別,經過設定,訊息可以做到0丟失,用java語言開發的,比較容易做擴充套件或二次開發,是目前比較多的訊息佇列。
  • Kafka:吞吐量很高,達到了幾十萬級別,也可以做到訊息0丟失,功能簡單,一般用於大數據領域做實時計算和日誌採集。

爲什麼你這兩個專案分別使用了RocketMQ和Kafka?

  • RocketMQ它的吞吐量很高,時延低,穩定性高。適合處理線上業務,比如在交易系統中傳遞訂單。所以我在秒殺系統中使用了它。
  • 而Kafka採用了非同步批次設計,這種設計使得它的效能很高,但是帶來的問題是它的響應時延比較高,當用戶端發送一條訊息時,Kafka 並不會立即發送出去,而是攢一批了再發送,所以 Kafka 不太適合線上業務的場景。在我的討論社羣專案中,如果有點贊,評論或者關注等操作,我需要去非同步進行訊息通知,對實時性要求不高,所以Kafka比較合適。