程序員都應(yīng)該知道的常用消息中間件以及RabbitMQ消息中間件
常用消息中間件
早期使用ActiveMQ作為消息中間件的項目比較多,作為Apache的一個子項目,ActiveMQ支持常用的多種語言:C++、Java、.Net、Python、PHP、Ruby等。
RabbitMQ是一個使用Erlang編寫的AMQP(高級消息隊列協(xié)議)的服務(wù)實現(xiàn)。簡單來說,它就是一個功能強大的消息隊列服務(wù)。

Kafka 是 最 早 使 用 Scala 實 現(xiàn) 的 一 個 高 性 能 分 布 式Publish/Subscribe消息隊列系統(tǒng),具有快速持久化、高吞吐、離線堆積等特性,在實時計算、日志采集等場景和大數(shù)據(jù)領(lǐng)域已經(jīng)成為業(yè)內(nèi)的標準。
RocketMQ作為一款純Java、分布式、隊列模型的開源消息中間件,參考了優(yōu)秀的開源消息中間件Kafka,支持事務(wù)消息、順序消息、批量消息、定時消息、消息回溯等。目前,在金融公司和以消息可靠性、低延遲為主要訴求的場景下RabbitMQ使用得比較多;而Kafka則在日志、數(shù)據(jù)流轉(zhuǎn)、大數(shù)據(jù)傳輸、高吞吐量等方面更有保障,后面我們還會對這兩種典型的消息中間件做進一步介紹。
RabbitMQ消息中間件
RabbitMQ本身支持很多協(xié)議:AMQP、XMPP、SMTP、STOMP,也正因如此,它才變得非常重量級,更適合企業(yè)級的開發(fā)。它的核心思想是生產(chǎn)者不會將消息直接發(fā)送給隊列,在發(fā)送給客戶端時消息先在中心隊列排隊。它對路由、負載均衡、數(shù)據(jù)持久化都有很好的支持。
RabbitMQ核心組件
RabbitMQ最核心的組件是Exchange和Queue。Exchange和Queue部署在RabbitMQ Broker,而Producer和Consumer部署在應(yīng)用端。
Virtual Host
Virtual Host(虛擬主機)類似權(quán)限控制組,一個Virtual Host里可以有多個Exchange和Queue,權(quán)限控制的最小粒度是VirtualHost。
Producer:即數(shù)據(jù)的發(fā)送方(生產(chǎn)者)一般一個Message有兩個部分:payload(有效載荷)和label(標簽),payload顧名思義就是傳輸?shù)臄?shù)據(jù),label是exchange的名字或者說是一個tag,它描述payload,而且RabbitMQ也通過label來決定把Message發(fā)給哪個Consumer。
Consumer:即數(shù)據(jù)的接收方(消費者)如果有多個Consumer同時訂閱同一個Queue中的消息,Queue中的消息會被分發(fā)給多個Consumer。
Connection與Channel
兩者都是RabbitMQ對外提供的API中最基本的對象。Connection是一個TCP的連接,Producer和Consumer都是通過TCP連接到RabbitMQServer的。
一個TCP建立后,客戶端會建立一個Channel(通信信道),每個Channel都被指派成唯一的ID。Channel是我們與RabbitMQ打交道的最重要的接口,我們的大部分業(yè)務(wù)操作是在Channel這個接口中完成的,包括定義Queue、定義Exchange、綁定Queue與Exchange、發(fā)布消息等。
Queue
Queue(隊列)是RabbitMQ的內(nèi)部對象,用來存儲信息。應(yīng)用程序在權(quán)限范圍內(nèi)可以自由地創(chuàng)建、共享、使用和消費Queue。Queue提供有限制的先進先出保證,服務(wù)器會將某一個Producer發(fā)出的同等優(yōu)先級消息按照它們進入隊列的順序傳遞給某一個Consumer,Queue可以是持久的、臨時的或者自動刪除的。Queue可以保存在內(nèi)存、硬盤或者兩種介質(zhì)的組合中,在Virtual Host范圍之內(nèi),Queue保存消息,并將消息分發(fā)給一個或者多個訂閱客戶端。
綁定
所謂綁定就是將一個特定的Exchange與一個特定的Queue綁定起來,綁定的關(guān)鍵字是BindingKey。Exchange和Queue的綁定可以是多對多的關(guān)系,每個發(fā)送給Exchange的消息都有一個叫作RoutingKey的關(guān)鍵字,Exchange要將該消息轉(zhuǎn)發(fā)給特定隊列,該隊列與交換器的BindingKey必須與消息的RoutingKey相匹配。
Exchange(交換器)
Exchange用于轉(zhuǎn)發(fā)消息,但是它不會做存儲,如果沒有Queue綁定到Exchange,它會直接丟棄Producer發(fā)送過來的消息。這里有一個比較重要的概念:路由鍵(RoutingKey)。當消息發(fā)送到Exchange的時候,Exchange會將其轉(zhuǎn)發(fā)到對應(yīng)的隊列中,至于轉(zhuǎn)發(fā)到哪個隊列取決于路由鍵。
Exchange的功能是接收消息并且轉(zhuǎn)發(fā)到綁定的隊列,Exchange不存儲消息,在啟用ACK模式后,Exchange找不到隊列會返回錯誤。
Exchange有四種類型:Direct、Fanout、Topic和Headers。
● Direct(默認):直接交換器
這 種 方 式 類 似 于 單 播 , Exchange 會 將 消 息 發(fā) 送 給 完 全 匹 配RoutingKey的Queue。下圖是直接交換器的工作方式:當某個消息到達交換器X時,如果它的RoutingKey是orange,它將直接被交給Queue1,如果是green,直接被交給Queue2。

● Fanout:廣播式交換器
不管消息的RoutingKey是什么,交換器都會將消息轉(zhuǎn)發(fā)給所有綁定的Queue。廣播式交換器的工作方式如下圖所示:發(fā)送到交換器X的所有消息都被無條件地發(fā)到所有綁定的Queue上。

● Topic:主題交換器
這種方式類似于組播,交換器會將消息轉(zhuǎn)發(fā)給和RoutingKey匹配模式相同的所有隊列,比如RoutingKey為orange的Message會轉(zhuǎn)發(fā)給綁定匹配模式為*.orange*和#.orange.#的隊列(*表示是匹配一個任意詞組,#表示匹配0個或多個詞組),如下圖所示。

● Headers:消息體的Header匹配(ignore)
與Routing不同的地方是,Header模式取消了RoutingKey,使用Header中的Key/value(鍵/值對)進行匹配。
訂閱模式與檢索模式
RabbitMQ支持兩種消息處理模式,一種是訂閱模式(Push模式),由Broker主動將消息推送給訂閱隊列的Consumer;另一種是檢索模式(Pull模式),需要Consumer調(diào)用channel.basicGet方法主動從隊列中拉取消息。
● 訂閱模式(Push)
實現(xiàn)一個Consumer,最容易的方式是繼承DefaultConsumer類實現(xiàn)訂閱模式,重寫其中的方法即可,具體使用示例如下:

這里因為關(guān)閉了消息自動確認機制,所以我們必須手動在handleDelivery方法中確認消息已經(jīng)消費處理成功。
● 檢索模式(Pull)
使用Channel.basicGet拉取消息,返回的數(shù)據(jù)類型是GetResponse實例。

同樣,由于這里設(shè)置了“autoAck=false;”,我們必須手動確認已經(jīng)成功接收到了消息。
本文給大家講解的內(nèi)容是MOM異步通信,常用消息中間件以及RabbitMQ消息中間件
下篇文章給大家講解的內(nèi)容是MOM異步通信,Kafka消息中間件
覺得文章不錯的朋友可以轉(zhuǎn)發(fā)此文關(guān)注小編;
感謝大家的支持!
本文就是愿天堂沒有BUG給大家分享的內(nèi)容,大家有收獲的話可以分享下,想學習更多的話可以到微信公眾號里找我,我等你哦。
