文章摘要:本篇文章為RabbitMQ的入門文章,不像其他一些程序代碼和應(yīng)用實(shí)戰(zhàn)性的文章會(huì)帶著大家從一個(gè)“Hello World”的簡(jiǎn)單例子出發(fā),在該篇幅中主要給大家講下RabbitMQ消息隊(duì)列的起源、為何要選擇該款組件、幾個(gè)主要的功能特性,讓大家對(duì)該款消息隊(duì)列組件有一個(gè)大概的認(rèn)識(shí)
在說(shuō)RabbitMQ之前有必要先來(lái)介紹下AMQP協(xié)議。AMQP,即Advanced Message Queuing Protocol,高級(jí)消息隊(duì)列協(xié)議,是應(yīng)用層協(xié)議的一個(gè)開(kāi)放標(biāo)準(zhǔn),為面向消息的中間件設(shè)計(jì)。AMQP的主要特征是面向消息、隊(duì)列、路由(包括點(diǎn)對(duì)點(diǎn)和發(fā)布/訂閱)、可靠性、安全。
那么再來(lái)介紹下RabbitMQ本身。RabbitMQ是一個(gè)上面說(shuō)的AMQP協(xié)議的開(kāi)源實(shí)現(xiàn),其服務(wù)器端用Erlang語(yǔ)言寫的,支持多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。該消息隊(duì)列主要用于在分布式系統(tǒng)中存儲(chǔ)轉(zhuǎn)發(fā)消息,在易用性、擴(kuò)展性、高可用性等方面表現(xiàn)不俗。
一、為何要選型RabbitMQ
(1)RabbitMQ本身安裝部署(單實(shí)例/集群)均較為簡(jiǎn)單,上手門檻低,功能豐富,符合AMQP標(biāo)準(zhǔn);
(2)RabbitMQ的集群易于擴(kuò)縮,可以根據(jù)實(shí)際的業(yè)務(wù)訪問(wèn)量,通過(guò)增減集群中節(jié)點(diǎn)實(shí)例的方式,達(dá)到彈性擴(kuò)容、縮小的效果;
(3)企業(yè)級(jí)消息隊(duì)列中間件,經(jīng)過(guò)業(yè)界各個(gè)公司生產(chǎn)環(huán)境大量實(shí)踐案例的驗(yàn)證,具有較高的可靠性;
(4)提供各種插件,比如RabbitMQ Management插件提供友好的Web頁(yè)面管理;
(5)除了Web頁(yè)面可以對(duì)RabbitMQ的單實(shí)例和集群的各種參數(shù)(Exchanges/Queues/Connections等)進(jìn)行監(jiān)控以外,其還提供Http的Api接口/JMX接口可以方便用戶根據(jù)業(yè)務(wù)需求進(jìn)行各種自定義的MQ級(jí)監(jiān)控;
(6)支持消息持久化、支持消息確認(rèn)機(jī)制、靈活的任務(wù)分發(fā)機(jī)制等,支持功能非常豐富;
(7)實(shí)現(xiàn)高可用性,可以在RabbitMQ集群中的機(jī)器上創(chuàng)建隊(duì)列的鏡像,使得在部分節(jié)點(diǎn)出問(wèn)題的情況下隊(duì)列仍然可用;此外,其warren和Shovel模式,可以實(shí)現(xiàn)故障轉(zhuǎn)移能力和跨數(shù)據(jù)中心的異地復(fù)制;
二、RabbitMQ應(yīng)用場(chǎng)景下的架構(gòu)圖
對(duì)于一般的童鞋來(lái)說(shuō),都是以自己用RabbitMQ消息隊(duì)列為目標(biāo)的(后面篇幅會(huì)對(duì)RabbitMQ產(chǎn)品云化的系統(tǒng)架構(gòu)圖加以詳細(xì)描述),下面給出了RabbitMQ應(yīng)用場(chǎng)景的系統(tǒng)架構(gòu)圖:

三、RabbitMQ消息隊(duì)列基本概念
(1)RabbitMQ Server:也可以稱為RabbitMQ Broker Server,其維護(hù)一條從Producer到Consumer的路線(Connection),保證數(shù)據(jù)能夠按照指定的方式進(jìn)行傳輸。
(2)Virtual Host虛擬主機(jī),表示一批交換器、消息隊(duì)列和相關(guān)對(duì)象的容器。虛擬主機(jī)是共享相同的身份認(rèn)證和加密環(huán)境的獨(dú)立服務(wù)器域。每個(gè) vhost 本質(zhì)上就是一個(gè) mini 版的 RabbitMQ 服務(wù)器,擁有自己的隊(duì)列、交換器、綁定和權(quán)限機(jī)制(相當(dāng)于是虛擬機(jī)和物理機(jī)的概念,可以起到租戶用戶隔離)。vhost 是 AMQP 概念的基礎(chǔ),必須在連接時(shí)指定,RabbitMQ 默認(rèn)的 vhost 是 “/”;
(3)Connection: 連接,Producer和Consumer都是通過(guò)TCP連接到RabbitMQ Server的。一般我們會(huì)看到,在我們業(yè)務(wù)代碼的起始為止就是建立這個(gè)TCP連接。
(4)Channels: 信道,它建立在上述的TCP連接中。數(shù)據(jù)流動(dòng)都是在Channel中進(jìn)行的。也就是說(shuō),代碼開(kāi)始處第一步是先建立TCP連接(上面(2)步驟),第二步就是建立這個(gè)Channel。
(5)Exchange:消息的生產(chǎn)者將消息發(fā)送到Exchange(交換器),由Exchange將消息路由到一個(gè)或多個(gè)Queue中(或者丟棄)。Exchange并不存儲(chǔ)消息。RabbitMQ中的Exchange有fanout、direct、topic、headers四種類型,每種類型對(duì)應(yīng)不同的路由規(guī)則。其中,headers 匹配 AMQP 消息的 header 而不是路由鍵,此外 headers 交換器和 direct 交換器完全一致,但性能差很多,目前幾乎用不到了,所以一般在業(yè)務(wù)應(yīng)用中只需要關(guān)注其他三種類型即可:
a.direct:消息中的路由鍵(routing key)如果和 Binding 中的 binding key 一致, 交換器就將消息發(fā)到對(duì)應(yīng)的隊(duì)列中。路由鍵與隊(duì)列名完全匹配,如果一個(gè)隊(duì)列綁定到交換機(jī)要求路由鍵為“dog”,則只轉(zhuǎn)發(fā) routing key 標(biāo)記為“dog”的消息,不會(huì)轉(zhuǎn)發(fā)“dog.puppy”,也不會(huì)轉(zhuǎn)發(fā)“dog.guard”等等。它是完全匹配、單播的模式;
b.fanout:每個(gè)發(fā)到 fanout 類型交換器的消息都會(huì)分到所有綁定的隊(duì)列上去。fanout 交換器不處理路由鍵,只是簡(jiǎn)單的將隊(duì)列綁定到交換器上,每個(gè)發(fā)送到交換器的消息都會(huì)被轉(zhuǎn)發(fā)到與該交換器綁定的所有隊(duì)列上。很像子網(wǎng)廣播,每臺(tái)子網(wǎng)內(nèi)的主機(jī)都獲得了一份復(fù)制的消息。fanout 類型轉(zhuǎn)發(fā)消息是最快的;
c.topic:交換器通過(guò)模式匹配分配消息的路由鍵屬性,將路由鍵和某個(gè)模式進(jìn)行匹配,此時(shí)隊(duì)列需要綁定到一個(gè)模式上。它將路由鍵和綁定鍵的字符串切分成單詞,這些單詞之間用點(diǎn)隔開(kāi)。它同樣也會(huì)識(shí)別兩個(gè)通配符:符號(hào)“#”和符號(hào)“”。#匹配0個(gè)或多個(gè)單詞,匹配不多不少一個(gè)單詞;
(6)Queue:隊(duì)列,其為RabbitMQ的內(nèi)部對(duì)象,用于存儲(chǔ)消息。消息消費(fèi)者就是通過(guò)訂閱隊(duì)列來(lái)獲取消息的,RabbitMQ中的消息都只能存儲(chǔ)在Queue中,生產(chǎn)者生產(chǎn)消息并最終投遞到Queue中,消費(fèi)者可以從Queue中獲取消息并消費(fèi)。多個(gè)消費(fèi)者可以訂閱同一個(gè)Queue,這時(shí)Queue中的消息會(huì)被平均分?jǐn)偨o多個(gè)消費(fèi)者進(jìn)行處理,而不是每個(gè)消費(fèi)者都收到所有的消息并處理。
(7)RoutingKey:生產(chǎn)者在將消息發(fā)送給Exchange的時(shí)候,一般會(huì)指定一個(gè)routing key,用于指定這個(gè)消息的路由規(guī)則。而這個(gè)routing key需要與Exchange Type及binding key聯(lián)合使用才能最終生效。在Exchange Type與binding key固定的情況下(在正常使用時(shí)一般這些內(nèi)容都是固定配置好的),我們的生產(chǎn)者就可以在發(fā)送消息給Exchange時(shí),通過(guò)指定routing key來(lái)決定消息流向哪里。RabbitMQ為routing key設(shè)定的長(zhǎng)度限制為255 bytes。
四、結(jié)論
看完以上對(duì)于RabbitMQ的特點(diǎn)描述即可知道,該款消息隊(duì)列中間件主要考慮的是高可靠性、功能強(qiáng)大、易于管理,對(duì)于消息隊(duì)列的吞吐量、消息積壓、并發(fā)性能等特點(diǎn)都與Kafka這種適用于大數(shù)據(jù)、流計(jì)算處理、日志收集的消息隊(duì)列組件(在特定場(chǎng)景下,比如日志收集,及時(shí)有消息丟失也能容忍的)有著不小的差距。個(gè)人覺(jué)得誰(shuí)是最好的消息組件這個(gè)命題沒(méi)有一個(gè)完整的結(jié)論,選擇適合自己使用和業(yè)務(wù)需求的就行了。