什么是消息隊列


一、什么是消息隊列?

消息隊列(Message Queue),是分布式系統中重要的組件,其通用的使用場景可以簡單地描述為:
當不需要立即獲得結果,但是並發量又需要進行控制的時候,差不多就是需要使用消息隊列的時候

二、消息隊列有什么用?

1. 提高響應速度

異步處理,串行化的功能變成並行化,從而提升系統性能,縮短響應時間
常用於秒殺、發送短信通知等,需要立即返回結果的場景

2. 流量控制

在高並發的情況,為了避免大量的請求沖擊后端服務,可以使用消息隊列暫存請求,后端服務按照自己的重能力,從隊列中消費,例如秒殺、埋點場景。
這樣可以隨時增加服務的實例數量水平擴容,而不用對系統的其他部分做修改

3.系統解耦

例如一個下單的信息需要同步多個子系統,每個子系統都需要保存訂單的數據的一部分,如果光靠訂單服務的團隊去維護所有的子系統數據同步,代價太大
解決方法是,通過發布訂閱模型,訂單服務在訂單變化時發送一條消息到一個主題中,所有的下游子系統都訂單主題,這樣可以每個子系統都可以獲得一份完整的訂單數據
即使是增加、減少子系統,也不會對訂單服務造成影響

三、消息隊列有什么缺點?

  1. 同步消息改成了異步,增加了系統的調用鏈,增加了系統的復雜度
  2. 降低了數據一致性,如果要保持一致性,需要高代價的補償(如分布式事務、對賬)
  3. 引入了消息隊列帶來的延遲問題

四、常見的消息隊列

RabbitMQ

https://www.rabbitmq.com/
優點:輕量,迅捷,容易部署和使用,擁有靈活的路由配置
缺點:性能和吞吐量較差,由於其采用的是Erlang語言不易進行二次開發

RocketMQ

http://activemq.apache.org/
優點:性能好,穩定可選,有活躍的中文社區,實時性比較好,
缺點:但是兼容性較差,但隨影響力的擴大,以后會有改善

Kafka

http://kafka.apache.org/
優點:擁有強大的性能及吞吐量,在大數據和流計算領域,幾乎所有的相關開源軟件都會優先支持kafka
缺點:當消息數量沒有那么多的時候,時延會比較高

五、消息隊列的兩種模型

1. 點對點模型

  • 每個消息只有一個接收者(Consumer),一旦被消息,就不再在消息隊列中
  • 發送者和接收者間沒有依賴性,發送者發送消息后,不管有沒有接收者在運行,不會影響下一次發送

2. 發布訂閱模型

  • 每個消息可以有多個訂閱者
  • 每個訂閱者都可以接收到主題的所有消息

兩種模型區別

兩個模型的區別:一份消息是否能被多次消費
如果只有一個訂閱者,兩個模型基本一樣,所以發布訂閱模型在功能層面是兼容隊列模型的

六、消息隊列如何實現分布式事務

一個嚴格意義的事務實現是ACID4個屬性:原子性、一致性、隔離性、持久性

  • 原子性:一個事務操作不可分割,要么全部成功,要么全部失敗,不能一半成功一半失敗
  • 一致性:事務執行完成之前的時間點,讀到的一定是更新前的數據,之后讀到的一定是更新后的數據
  • 隔離性:一個事務的執行不能被其他事務干擾(一個事務內部的操作及使用的數據對正在進行的其他事務是隔離的,並發執行的各個事務之間不能互相干擾)
  • 持久性:事務一旦提交,后續的其他操作和故障都不會對事務的結果有任何影響

在分布式系統中,光是要實現數據一致性就已經非常困難了,所以一般只保證達到最終一致性。比較常見的分布式事務實現有

  1. 2PC(Two-phase Commit)二階段提交
  2. TCC(Try-Confirm-Cancel)
  3. 事務消息

消息隊列分布式事務實現

Kafka和RocketMQ都提供了事務相關功能,下面以訂單為例看下如何如何實現的

Kafka和RocketMQ都提供了事務相關功能,核心:半消息
”半消息“:這個半消息不是指消息內容不完整,而是指在事務提交前,對於消費者來說,這個消息是不可見的(sendMessageInTransaction)

如果數據庫事務提交失敗怎么辦

  1. 業務代碼中反復重試提交,直到提交成功
  2. 刪除之前創建的訂單進行補償
  3. 提供一個反查本地事務狀態接口給MQ,告知成功或失敗(RocketMQ支持)


免責聲明!

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



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