消息隊列-RabbitMQ-基礎(chǔ)入門

RabbitMQ基本概念

我們先看一下RabbitMQ模型結(jié)構(gòu)圖,這樣會方便們更好地去理解RabbitMQ的基本原理。

image.png

通過上面這張應(yīng)用相結(jié)合的結(jié)構(gòu)圖既能夠清晰的看清楚整體的send Message到Receive Message的一個大致的流程尿孔。當(dāng)然上面有很多名詞都相比還沒有介紹到鲁猩,不要著急接下來我們就開始對其進行詳細的講解适滓。

Queue

Queue(隊列)RabbitMQ的作用是存儲消息澳窑,隊列的特性是先進先出。上圖可以清晰地看到Client A和Client B是生產(chǎn)者玻驻,生產(chǎn)者生產(chǎn)消息最終被送到RabbitMQ的內(nèi)部對象Queue中去悼凑,而消費者則是從Queue隊列中取出數(shù)據(jù)偿枕。可以簡化成表示為:

image.png

生產(chǎn)者Send Message “A”被傳送到Queue中户辫,消費者發(fā)現(xiàn)消息隊列Queue中有訂閱的消息渐夸,就會將這條消息A讀取出來進行一些列的業(yè)務(wù)操作。這里只是一個消費正對應(yīng)一個隊列Queue渔欢,也可以多個消費者訂閱同一個隊列Queue墓塌,當(dāng)然這里就會將Queue里面的消息平分給其他的消費者,但會存在一個問題:如果每個消息的處理時間不同奥额,就會導(dǎo)致某些消費者一直在忙碌中苫幢,而有的消費者處理完了消息后一直處于空閑狀態(tài),因為前面已經(jīng)提及到了Queue會平分這些消息給相應(yīng)的消費者垫挨。這里我們就可以使用prefetchCount來限制每次發(fā)送給消費者消息的個數(shù)韩肝。詳情見下圖所示:

image.png

這里的prefetchCount=1是指每次從Queue中發(fā)送一條消息來。等消費者處理完這條消息后Queue會再發(fā)送一條消息給消費者九榔。

Exchange

回憶一下哀峻,在開篇TabbitMQ消息模型圖中,消費者Client A和消費者Client B是如何知道我發(fā)送的消息是給Queue1還是給Queue2哲泊。首先明確一點就是生產(chǎn)者產(chǎn)生的消息并不是直接發(fā)送給消息隊列Queue的谜诫,而是要經(jīng)過Exchange(交換器),由Exchange再將消息路由到一個或多個Queue攻旦,當(dāng)然這里還會對不符合路由規(guī)則的消息進行丟棄掉,這里指的是后續(xù)要談到的Exchange Type生逸。那么Exchange是怎樣將消息準(zhǔn)確的推送到對應(yīng)的Queue的呢牢屋?那么這里的功勞最大的當(dāng)屬Binding,RabbitMQ是通過Binding將Exchange和Queue鏈接在一起槽袄,這樣Exchange就知道如何將消息準(zhǔn)確的推送到Queue中去烙无。簡單示意圖如下所示:

image.png

在綁定(Binding)Exchange和Queue的同時,一般會指定一個Binding Key遍尺,生產(chǎn)者將消息發(fā)送給Exchange的時候截酷,一般會產(chǎn)生一個Routing Key,當(dāng)Routing Key和Binding Key對應(yīng)上的時候乾戏,消息就會發(fā)送到對應(yīng)的Queue中去迂苛。那么Exchange有四種類型,不同的類型有著不同的策略鼓择。也就是表明不同的類型將決定綁定的Queue不同三幻,換言之就是說生產(chǎn)者發(fā)送了一個消息,Routing Key的規(guī)則是A呐能,那么生產(chǎn)者會將Routing Key=A的消息推送到Exchange中念搬,這時候Exchange中會有自己的規(guī)則,對應(yīng)的規(guī)則去篩選生產(chǎn)者發(fā)來的消息,如果能夠?qū)?yīng)上Exchange的內(nèi)部規(guī)則就將消息推送到對應(yīng)的Queue中去朗徊。那么接下來就來詳細講解下Exchange里面類型首妖。

Exchange Type

我來用表格來描述下類型以及類型之間的區(qū)別。

fanout

fanout類型的Exchange路由規(guī)則非常簡單爷恳,它會把所有發(fā)送到該Exchange的消息路由到所有與它綁定的Queue中有缆。

image.png

上圖所示,生產(chǎn)者(P)生產(chǎn)消息1將消息1推送到Exchange舌仍,由于Exchange Type=fanout這時候會遵循fanout的規(guī)則將消息推送到所有與它綁定Queue妒貌,也就是圖上的兩個Queue最后兩個消費者消費。

direct

direct類型的Exchange路由規(guī)則也很簡單铸豁,它會把消息路由到那些binding key與routing key完全匹配的Queue中

image.png

當(dāng)生產(chǎn)者(P)發(fā)送消息時Rotuing key=booking時灌曙,這時候?qū)⑾魉徒oExchange,Exchange獲取到生產(chǎn)者發(fā)送過來消息后节芥,會根據(jù)自身的規(guī)則進行與匹配相應(yīng)的Queue在刺,這時發(fā)現(xiàn)Queue1和Queue2都符合,就會將消息傳送給這兩個隊列头镊,如果我們以Rotuing key=create和Rotuing key=confirm發(fā)送消息時蚣驼,這時消息只會被推送到Queue2隊列中,其他Routing Key的消息將會被丟棄相艇。

topic

前面提到的direct規(guī)則是嚴(yán)格意義上的匹配颖杏,換言之Routing Key必須與Binding Key相匹配的時候才將消息傳送給Queue,那么topic這個規(guī)則就是模糊匹配坛芽,可以通過通配符滿足一部分規(guī)則就可以傳送留储。它的約定是:

  1. routing key為一個句點號.分隔的字符串(我們將被句點號.分隔開的每一段獨立的字符串稱為一個單詞),如“stock.usd.nyse”咙轩、“nyse.vmw”获讳、“quick.orange.rabbit”
  2. binding key與routing key一樣也是句點號.分隔的字符串
  3. binding key中可以存在兩種特殊字符*#,用于做模糊匹配活喊,其中*用于匹配一個單詞丐膝,#用于匹配多個單詞(可以是零個)
image.png

當(dāng)生產(chǎn)者發(fā)送消息Routing Key=F.C.E的時候,這時候只滿足Queue1钾菊,所以會被路由到Queue中帅矗,如果Routing Key=A.C.E這時候會被同是路由到Queue1和Queue2中,如果Routing Key=A.F.B時结缚,這里只會發(fā)送一條消息到Queue2中损晤。

headers

headers類型的Exchange不依賴于routing key與binding key的匹配規(guī)則來路由消息,而是根據(jù)發(fā)送的消息內(nèi)容中的headers屬性進行匹配红竭。 在綁定Queue與Exchange時指定一組鍵值對尤勋;當(dāng)消息發(fā)送到Exchange時喘落,RabbitMQ會取到該消息的headers(也是一個鍵值對的形式),對比其中的鍵值對是否完全匹配Queue與Exchange綁定時指定的鍵值對;如果完全匹配則消息會路由到該Queue最冰,否則不會路由到該Queue瘦棋。 該類型的Exchange沒有用到過(不過也應(yīng)該很有用武之地),所以不做介紹暖哨。

這里在對其進行簡要的表格整理:

小結(jié)

img

核心概念:
Server:又稱Broker ,接受客戶端的連接赌朋,實現(xiàn)AMQP實體服務(wù)。 安裝rabbitmq-server
Connection:連接篇裁,應(yīng)用程序與Broker的網(wǎng)絡(luò)連接 TCP/IP/ 三次握手和四次揮手
Channel:網(wǎng)絡(luò)信道沛慢,幾乎所有的操作都在Channel中進行,Channel是進行消息讀寫的通道达布,客戶端可以建立對各Channel团甲,每個Channel代表一個會話任務(wù)。
Message :消息:服務(wù)與應(yīng)用程序之間傳送的數(shù)據(jù)黍聂,由Properties和body組成躺苦,Properties可是對消息進行修飾,比如消息的優(yōu)先級产还,延遲等高級特性匹厘,Body則就是消息體的內(nèi)容。
Virtual Host 虛擬地址脐区,用于進行邏輯隔離愈诚,最上層的消息路由,一個虛擬主機理由可以有若干個Exhange和Queueu牛隅,同一個虛擬主機里面不能有相同名字的Exchange
Exchange:交換機扰路,接受消息,根據(jù)路由鍵發(fā)送消息到綁定的隊列倔叼。(==不具備消息存儲的能力==)
Bindings:Exchange和Queue之間的虛擬連接,binding中可以保護多個routing key.
Routing key:是一個路由規(guī)則宫莱,虛擬機可以用它來確定如何路由一個特定消息丈攒。
Queue:隊列:也成為Message Queue,消息隊列,保存消息并將它們轉(zhuǎn)發(fā)給消費者授霸。

類型名稱 類型描述
fanout 把所有發(fā)送到該Exchange的消息路由到所有與它綁定的Queue中
direct Routing Key==Binding Key
topic 簡稱模糊匹配巡验,*用于匹配一個單詞,#用于匹配多個單詞(可以是零個)
headers Exchange不依賴于routing key與binding key的匹配規(guī)則來路由消息碘耳,而是根據(jù)發(fā)送的消息內(nèi)容中的headers屬性進行匹配显设。

消息發(fā)送與接收原理

消息發(fā)送與接收的整體流程如下圖所示,后面會再分別針對發(fā)送和接收展開介紹:

img

消息發(fā)布原理

如下圖所示辛辨,生產(chǎn)者將消息投遞給exchange捕捂,exchange與queue之間已經(jīng)事先建立好了某個路由規(guī)則binding瑟枫,exchange根據(jù)routingKey和事先建立好的binding進行匹配,決定如何將消息分發(fā)給對應(yīng)的queue指攒。

消息發(fā)送的原型.png

消息消費原理

消費者訂閱指定queue慷妙,當(dāng)消息發(fā)送到queue之后,由于RabbitMQ消息消費采用的是push模型允悦,queue會立即將消息發(fā)送給訂閱了該queue的消費者膝擂。

  • 如果多個訂閱者訂閱同一個queue,則消息只會發(fā)給其中一個訂閱者
  • 生產(chǎn)者發(fā)送一條消息隙弛,希望多個訂閱者可以消費(消息廣播的場景)架馋,多個訂閱者就每個人分別訂閱一個隊列,其中每個隊列和exchange建立相同的binding全闷。
消息訂閱原型.png

要特別注意的是叉寂,這種方案實現(xiàn)的消息廣播是有瓶頸限制的。因為RabbitMQ進行隊列廣播時室埋,是需要在內(nèi)存中復(fù)制消息的办绝,如果廣播的量不大,10姚淆、20個這樣的孕蝉,對性能影響不大;但如果是大量的廣播腌逢,則會急劇降低RabbitMQ的性能降淮。因此MQ并不適合對端推送,相比較而言搏讶,更適用于服務(wù)間推送佳鳖。

補充說明

ConnectionFactory、Connection媒惕、Channel都是RabbitMQ對外提供的API中最基本的對象系吩。Connection是RabbitMQ的socket鏈接,它封裝了socket協(xié)議相關(guān)部分邏輯妒蔚。ConnectionFactory為Connection的制造工廠穿挨。Channel是我們與RabbitMQ打交道的最重要的一個接口,我們大部分的業(yè)務(wù)操作是在Channel這個接口中完成的肴盏,包括定義Queue科盛、定義Exchange、綁定Queue與Exchange菜皂、發(fā)布消息等贞绵。

Connection就是建立一個TCP連接,生產(chǎn)者和消費者的都是通過TCP的連接到RabbitMQ Server中的恍飘,這個后續(xù)會再程序中體現(xiàn)出來榨崩。

Channel虛擬連接谴垫,建立在上面TCP連接的基礎(chǔ)上,數(shù)據(jù)流動都是通過Channel來進行的蜡饵。為什么不是直接建立在TCP的基礎(chǔ)上進行數(shù)據(jù)流動呢弹渔?如果建立在TCP的基礎(chǔ)上進行數(shù)據(jù)流動,建立和關(guān)閉TCP連接有代價溯祸。頻繁的建立關(guān)閉TCP連接對于系統(tǒng)的性能有很大的影響肢专,而且TCP的連接數(shù)也有限制,這也限制了系統(tǒng)處理高并發(fā)的能力焦辅。但是博杖,在TCP連接中建立Channel是沒有上述代價的。

參考資料

  1. 消息中間件RabbitMq
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末筷登,一起剝皮案震驚了整個濱河市剃根,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌前方,老刑警劉巖狈醉,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異惠险,居然都是意外死亡苗傅,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門班巩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渣慕,“玉大人,你說我怎么就攤上這事抱慌⊙疯耄” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵抑进,是天一觀的道長强经。 經(jīng)常有香客問我,道長寺渗,這世上最難降的妖魔是什么夕凝? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮户秤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逮矛。我一直安慰自己鸡号,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布须鼎。 她就那樣靜靜地躺著鲸伴,像睡著了一般府蔗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上汞窗,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天姓赤,我揣著相機與錄音,去河邊找鬼仲吏。 笑死不铆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的裹唆。 我是一名探鬼主播誓斥,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼许帐!你這毒婦竟也來了劳坑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤成畦,失蹤者是張志新(化名)和其女友劉穎距芬,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體循帐,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡框仔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了惧浴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片存和。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖衷旅,靈堂內(nèi)的尸體忽然破棺而出捐腿,到底是詐尸還是另有隱情,我是刑警寧澤柿顶,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布茄袖,位于F島的核電站,受9級特大地震影響嘁锯,放射性物質(zhì)發(fā)生泄漏宪祥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一家乘、第九天 我趴在偏房一處隱蔽的房頂上張望蝗羊。 院中可真熱鬧,春花似錦仁锯、人聲如沸耀找。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽野芒。三九已至蓄愁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間狞悲,已是汗流浹背撮抓。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留摇锋,地道東北人丹拯。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像乱投,于是被迫代替她去往敵國和親咽笼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345