一、什么是MQ
MQ(MessageQueue)
Message(消息):消息是在不同進程之間傳遞的數據,這些進程可以在同一臺機器上,也可以在不同的機器上。
Queue(隊列):隊列原意是指一種具有FIFO(先進先出)特性的數據結構,是用來緩存數據的。
我們要學習的MQ產品對接的使用對象是應用程序。
它是一種在應用程序之間傳遞消息的通信方式,通過將消息發送到中間件(消息隊列)來實現解耦和異步處理。消息隊列允許發送者將消息放入隊列中,而接收者可以從隊列中獲取消息進行處理。這種方式可以提高系統的可靠性、擴展性和靈活性,同時降低系統之間的依賴性和耦合度。常見的消息隊列系統有RabbitMQ、Apache Kafka、RocketMQ。
二、MQ有什么作用
MQ的主要作用包括:
-
異步通信:通過消息隊列,發送者和接收者之間的通信可以變為異步方式,發送者將消息放入隊列后即可繼續處理其他任務,而不需要等待接收者的響應。這能提高系統響應時間
-
解耦合:使用消息隊列可以將不同模塊或服務之間的耦合度降低。發送者只需要將消息發送到隊列中,而不需要關心具體的接收者是誰,接收者也可以從隊列中獲取消息進行處理,而不需要知道消息的來源。當下游服務出現問題無法提供服務時,不會影響到上游服務繼續提供服務,這一點在分布式系統中尤為重要。
-
緩沖和削峰:當發送者產生大量請求時,消息隊列可以作為緩沖區,暫時存儲這些請求,然后由接收者按照自己的處理能力逐個處理。同時,當請求過多導致系統壓力過大時,消息隊列可以平滑地削峰,避免系統崩潰或性能下降。
三、MQ介紹及選型
RabbitMQ
- 遵從AMQP協議
AMQP簡單來說就是規定好了MQ的各個抽象組件,使得很好被開源框架所集成,比如Spring AMQP專門就是用來操作AMQP架構的中間件的,因此RabbitMQ可以被Spring Boot很方便的集成。 - 豐富的消費模型:Fanout(廣播)、direct(精確路由)、topic(模糊路由)
- 消息延遲低(微秒級)
- 吞吐量不高
- 使用erlang語言,使得其根據業務進行二次開發的成本比較高
RocketMQ
RocketMQ出自阿里公司的開源產品,用 Java 語言實現,在設計時參考了 Kafka,并做出了自己的一些改進,消息可靠性上比 Kafka 更好。RocketMQ在阿里集團被廣泛應用在訂單,交易,充值,流計算,消息推送,日志流式處理,binglog分發等場景。
- 天生的分布式架構
- 消息可靠性和吞吐量都很高,以及豐富的消息消費模式使他適用于大多數業務場景
Kafka
Apache Kafka是一個分布式消息發布訂閱系統。它最初由LinkedIn公司基于獨特的設計實現為一個分布式的提交日志系統( a distributed commit log),之后成為Apache項目的一部分。Kafka系統快速、可擴展并且可持久化。它的分區特性,可復制和可容錯都是其不錯的特性。
- Kafka的設計目標是實現高吞吐量的消息傳遞,適用于處理大量的實時數據流。
- 支持的消費模式比較單一
具體企業開發中使用如何呢?
Kafka 一開始的目的就是用于日志收集和傳輸,適合有大量數據產生的互聯網業務,特別是大數據領域的實時計算、日志采集等場景,用 Kafka 絕對沒錯,社區活躍度高,業內標準。
RocketMQ 特別適用于金融互聯網領域這類對于可靠性要求很高的場景,比如訂單交易等,而且 RocketMQ 是阿里出品的,經歷過那么多次淘寶雙十一的考驗,大品牌,在穩定性值得信賴。但如果阿里不再維護這個技術了,社區有可能突然黃掉的風險。因此如果公司對自己的技術實力有自信,基礎架構研發實力較強,推薦用 RocketMQ。
RabbitMQ 適用于公司對外提供能力,可能會有很多主題接入的中臺業務場景,畢竟它是百萬級主題數的。它的時效性是毫秒級的,但實際毫秒級和微秒級在感知上沒有什么太大的區別,所以它的這一大優點并不太會作為考量標準。同時,它的功能是比較完善的,開源社區活躍度高,能解決開發中遇到的bug,所以萬級別數據量業務場景的小公司可以優先選擇功能完善的RabbitMQ。它的缺點就是用 Erlang 語言編寫,所以很多開發人員很難去看懂源碼并進行二次開發和維護,也就是說對于公司來說可能處于不可控的狀態。
RocketMQ的核心部分概述
生產者(Producer)
RocketMQ生產者是消息的發送方,用于向RocketMQ中的主題發布消息。生產者負責將消息發送到指定的主題,并將消息傳遞給訂閱該主題的消費者進行消費。
消費者(Consumer)
RocketMQ消費者是消息的接收方,用于從RocketMQ中的主題訂閱消息并進行消費。消費者負責從指定的主題中拉取消息或者監聽隊列,然后對消息進行處理。
消費者組(ConsumerGroup)
- 為了消費能力的水平擴展,ConsumerGroup的概念應運而生。
RocketMQ消費者組是一組具有相同消費邏輯的消費者實例的集合。在RocketMQ中,一個主題可以由多個消費者組進行訂閱和消費。
消費者組的主要作用是實現消息的負載均衡和容錯能力。當一個主題有多個消費者組時,RocketMQ會將該主題的消息分配給各個消費者組進行處理。每個消費者組內的消費者實例則共同承擔該組內消息的消費任務。這樣做的好處是能夠提高消息的消費速度和并發處理能力。
主題(Topic)
- 標識消息分類:RocketMQ的主題用于對消息進行分類和組織。通過為不同類型的消息分配不同的主題,可以使消息更具可讀性和可管理性。
- 獨立的消息隊列:每個主題都有自己的消息隊列,用于存儲該主題下的消息。每個隊列都可以并行地接收和處理消息,從而實現高吞吐量和負載均衡。
- 消息路由:生產者在發送消息時指定目標主題,消費者則通過訂閱感興趣的主題來接收對應的消息。RocketMQ根據主題將消息路由到相應的隊列上,然后再由消費者消費。
NameServer
RocketMQ的NameServer是一個用于管理和維護消息隊列的元數據信息的組件。它是RocketMQ的核心組件之一,負責記錄每個Topic的路由信息和Broker的狀態信息。
Broker
在RocketMQ中,Broker是消息隊列的核心組件之一。它負責存儲和轉發消息,并提供消息的發布和訂閱功能。他是一個物理概念,你可以認為他是一個服務節點。
MessageQueue
定義: 隊列是 Apache RocketMQ 中消息存儲和傳輸的實際容器,也是 Apache RocketMQ 消息的最小存儲單元。 Apache RocketMQ 的所有主題都是由多個隊列組成,以此實現隊列數量的水平拆分和隊列內部的流式存儲。
為了消息寫入能力的水平擴展,RocketMQ 對 Topic進行了分區,這種操作被稱為隊列(MessageQueue)。
對于RocketMQ同一個消費者組下的多個consumer需要與topic下的messagequeue建立對應關系,而一個messagequeue只能被一個consumer進行消費。因此增加的Conusmer實例最多也只能和Topic下的MessageQueue數量相等,如果繼續增加就會有消費者空閑。