RabbitMQ:快速入門

和RocketMQ一樣堡赔,RabbitMQ作為消息中間件锰茉,主要負(fù)責(zé)接收倔既、存儲和轉(zhuǎn)發(fā)消息恕曲。同時RabbitMQ也有生產(chǎn)者和消費者的概念,我們先來看看其整體模型架構(gòu)渤涌。如下圖:

1. 核心概念介紹

1.1 生產(chǎn)者和消費者

  • Producer:生產(chǎn)者佩谣,投遞消息的一方。

通常來說实蓬,一條消息可以包含2個部分:消息體和標(biāo)簽茸俭。消息體一般是一個帶有業(yè)務(wù)邏輯結(jié)構(gòu)的數(shù)據(jù),而標(biāo)簽則用來描述這條消息瞳秽,比如一個交換機(jī)的名稱和一個路由鍵瓣履。

  • Consumer:消費者率翅,接收消息的一方练俐。

消費者連接到RabbitMQ服務(wù)器,并訂閱到隊列上冕臭。當(dāng)消費者消費一條消息時腺晾,只是消費消息的消息體,在消息路由的過程中辜贵,消息的標(biāo)簽會丟失悯蝉,存入到隊列中的消息只有消息體,實際上托慨,消費者也不需要關(guān)心消息的生產(chǎn)者是誰鼻由。

  • Broker:消息中間件所在的服務(wù)節(jié)點。

消息流轉(zhuǎn)過程如下:

1.2 隊列

  • Queue:隊列厚棵,是RabbitMQ的內(nèi)部對象蕉世,用于存儲消息。

RabbitMQ中消息都只能存儲在隊列中婆硬,這一點和RocketMQ不同狠轻,RocketMQ將消息存儲在topic這個邏輯層面,而相對應(yīng)的隊列邏輯只是topic實際存儲文件中的位移標(biāo)識彬犯。

多個消費者可以訂閱同一隊列向楼,這時隊列中的消息會被平均分?jǐn)偨o多個消費者進(jìn)行處理,而不是每個消費者都收到所有的消息并處理谐区。(類似RocketMQ中的負(fù)載均衡模式)

RabbitMQ不支持隊列層面的廣播消費(但并不是說RabbitMQ不支持廣播消費)湖蜕,RocketMQ是支持廣播消費的。

1.3 交換器宋列、路由鍵昭抒、綁定

  • Exchange:交換器,實際上消息生產(chǎn)者并不是直接將消息發(fā)送到隊列的。而是將消息發(fā)送給交換器戈鲁,由交換器將消息路由到一個或多個隊列中仇参。如果路由不到,或許會返回給生產(chǎn)者婆殿,或許直接丟棄诈乒。

其實從大的層面上來說芜繁,和RocketMQ消息投遞的設(shè)計理念是一樣的桩卵。在RocketMQ中,生產(chǎn)者也并不是直接往Broker投遞消息的置尔,而是通過NameServer和Topic共同決定投遞到某個Broker中消约。

  • RoutingKey:路由鍵肠鲫,生產(chǎn)者將消息發(fā)給交換器的時候,一般會指定一個RoutingKey或粮,用來指定這個消息的路由規(guī)則导饲,而這個RoutingKey需要與交換器類型和綁定鍵(BindingKey)聯(lián)合使用才能最終生效。
  • Binding:綁定氯材,RabbitMQ中通過綁定將交換器與隊列關(guān)聯(lián)起來渣锦,在綁定的時候一般會指定一個綁定鍵(BindingKey),這樣RabbitMQ就知道如何正確地將消息路由到隊列中了氢哮。

這里可能對路由鍵和綁定鍵存在一定的理解混淆袋毙,其實很簡單,綁定鍵就是一個連接交換器和隊列的關(guān)鍵詞冗尤,而路由鍵是交換器來根據(jù)自身類型以及綁定關(guān)系找到適配隊列的關(guān)鍵詞听盖。

雖然RocketMQ中沒有這樣的概念,但是RocketMQ中也有類似的設(shè)計理念裂七。生產(chǎn)者在發(fā)送一條消息時皆看,需要指定Topic,還可以指定Tags碍讯。訂閱了同一個Topic的消費者悬蔽,還可以根據(jù)Tags來判斷是否消費消息。也即間接的消費某一類消息捉兴,而不是消費這個Topic下所有的消息蝎困。

1.4 交換器類型

常用的交換器類型有fanoutdirect倍啥、topic這三種禾乘。

  • fanout

這種類型的交換器,它會把生產(chǎn)者發(fā)送的消息路由到所有與該交換器綁定的隊列中虽缕。也就是說始藕,此時交換器不會去理會RountingKey是什么了。

  • direct

這種類型的交換器,它會把生產(chǎn)者發(fā)送的消息路由到那些BindingKeyRoutingKey完全匹配的隊列中伍派。

  • topic

fanout類型的交換器太過于隨便江耀,direct類型的交換器又太過于嚴(yán)格。而topic類型的交換器正是介于fanoutdirect之間诉植,和direct類型的交換器類似祥国,也是講消息路由到BindingKeyRoutingKey相匹配的隊列中,但這里的匹配規(guī)則有些不同晾腔,它允許BindingKey中存在兩種特殊字符串*#用于做模糊匹配舌稀,其中*用來匹配一個單詞,#用來匹配0個或多個單詞灼擂。舉例:

1)壁查、路由鍵為"com.rabbitmq.client"的消息會同時路由到Queue1和Queue2中。

2)剔应、路由鍵為"com.hidden.client"的消息只會路由到Queue2中睡腿。

3)、路由鍵為"com.hidden.demo"的消息只會路由到Queue2中领斥。

4)嫉到、路由鍵為"java.rabbitmq.demo"的消息只會路由到Queue1中沃暗。

5)月洛、路由鍵為"java.util.concurrent"的消息將會被丟棄或者返回給生產(chǎn)者。

2. RabbitMQ運(yùn)轉(zhuǎn)流程

了解以上的RabbitMQ架構(gòu)模式以及相關(guān)概念孽锥,再結(jié)合《RabbitMQ:安裝》中的例子回顧一下整個消息隊列的使用過程嚼黔。

  • 生產(chǎn)者發(fā)送消息

    1. 生產(chǎn)者通過ConnectionFactory連接到RabbitMQ Broker(RocketMQ中,生產(chǎn)者和消費者是跟NameServer進(jìn)行連接的)惜辑,建立一個連接Connection唬涧,開啟一個信道Channel
    2. 生產(chǎn)者聲明一個交換器并設(shè)置相關(guān)屬性盛撑,比如交換器類型碎节、是否持久化等。
    3. 生產(chǎn)者聲明一個隊列并設(shè)置相關(guān)屬性抵卫,比如是否排他狮荔、是否持久化、是否自動刪除等介粘。
    4. 生產(chǎn)者通過路由鍵將交換器和隊列進(jìn)行綁定殖氏。
    5. 生產(chǎn)者發(fā)送消息至RabbitMQ Broker,其中包含路由鍵姻采、交換器等信息雅采。
    6. 相應(yīng)的交換器根據(jù)接收到的路由鍵查看相匹配的隊列。
    7. 如果找到,則將消息存入相應(yīng)的隊列中婚瓜;否則根據(jù)生產(chǎn)者配置的屬性選擇丟棄還是回退給生產(chǎn)者宝鼓。
    8. 關(guān)閉信道、關(guān)閉連接巴刻。

    實際上席函,在生產(chǎn)環(huán)境,交換器冈涧、隊列茂附、綁定關(guān)系是提前創(chuàng)建好的。不需要在生產(chǎn)者發(fā)送消息時顯示的聲明交換器督弓、隊列和綁定關(guān)系营曼。

  • 消費者消費消息
    1. 消費者連接到RabbitMQ Broker,建立一個連接愚隧,開啟一個信道蒂阱。
    2. 消費者向RabbitMQ Broker請求消費相應(yīng)隊列中的消息。
    3. 等到RabbitMQ Broker回應(yīng)并投遞相應(yīng)隊列中的消費狂塘,消費者接收消息录煤。
    4. 消費者確認(rèn)接收到的消息。
    5. RabbitMQ從隊列中刪除相應(yīng)已經(jīng)被確認(rèn)的消息荞胡。
    6. 關(guān)閉信息妈踊、關(guān)閉連接。

在這里泪漂,我們知道無論是生產(chǎn)者還是消費者廊营,都需要和RabbitMQ Broker建立連接,這個連接就是一條TCP連接萝勤,也就是Connection露筒。一旦TCP連接建立起來,客戶端緊接著可以創(chuàng)建一個信道Channel敌卓,每個信道都會被指派一個唯一的ID慎式。信道是建立在Connection之上的虛擬連接,RabbitMQ處理的每條指令都是通過信道完成的趟径。

我們完全可以直接使用Connection就能完成信道的工作瘪吏,為什么還要引入信道呢?試想這樣的一個場景舵抹,一個應(yīng)用程序中有很多線程需要從RabbitMQ中消費消息或者生產(chǎn)消息肪虎,那么必然需要建立很多個Connection,也就是許多個TCP連接惧蛹。然而對于操作系統(tǒng)而言扇救,建立和銷毀TCP連接都是非常昂貴的開銷刑枝,如果遇到使用高峰,性能瓶頸也隨之顯現(xiàn)迅腔。RabbitMQ采用類似NIO的做法装畅,選擇TCP連接富用,不僅可以減少性能開銷沧烈,同時也便于管理掠兄。

每個線程把持一個信道,所以信道復(fù)用了Connection的TCP連接锌雀。同時RabbitMQ可以確保每個線程的私密性蚂夕,就像擁有獨立的連接一樣。當(dāng)每個信道的流量不是很大時腋逆,復(fù)用單一的Connection可以在產(chǎn)生性能瓶頸的情況下有效地節(jié)省TCP連接資源婿牍。但是當(dāng)信道本身的流量很大時,這時候多個信道復(fù)用一個Connection就會產(chǎn)生性能瓶頸惩歉,進(jìn)而使整體的流量被限制了等脂。此時就需要開辟多個Connection,將這些信道均攤到這些Connection中撑蚌。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末上遥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子争涌,更是在濱河造成了極大的恐慌粉楚,老刑警劉巖,帶你破解...
    沈念sama閱讀 223,126評論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件第煮,死亡現(xiàn)場離奇詭異解幼,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)包警,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評論 3 400
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來底靠,“玉大人害晦,你說我怎么就攤上這事∈钪校” “怎么了壹瘟?”我有些...
    開封第一講書人閱讀 169,941評論 0 366
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鳄逾。 經(jīng)常有香客問我稻轨,道長,這世上最難降的妖魔是什么雕凹? 我笑而不...
    開封第一講書人閱讀 60,294評論 1 300
  • 正文 為了忘掉前任殴俱,我火速辦了婚禮政冻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘线欲。我一直安慰自己明场,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,295評論 6 398
  • 文/花漫 我一把揭開白布李丰。 她就那樣靜靜地躺著苦锨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪趴泌。 梳的紋絲不亂的頭發(fā)上舟舒,一...
    開封第一講書人閱讀 52,874評論 1 314
  • 那天,我揣著相機(jī)與錄音嗜憔,去河邊找鬼魏蔗。 笑死,一個胖子當(dāng)著我的面吹牛痹筛,可吹牛的內(nèi)容都是我干的莺治。 我是一名探鬼主播,決...
    沈念sama閱讀 41,285評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼帚稠,長吁一口氣:“原來是場噩夢啊……” “哼谣旁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起滋早,我...
    開封第一講書人閱讀 40,249評論 0 277
  • 序言:老撾萬榮一對情侶失蹤榄审,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后杆麸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搁进,經(jīng)...
    沈念sama閱讀 46,760評論 1 321
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,840評論 3 343
  • 正文 我和宋清朗相戀三年昔头,在試婚紗的時候發(fā)現(xiàn)自己被綠了饼问。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,973評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡揭斧,死狀恐怖莱革,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情讹开,我是刑警寧澤盅视,帶...
    沈念sama閱讀 36,631評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站旦万,受9級特大地震影響闹击,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜成艘,卻給世界環(huán)境...
    茶點故事閱讀 42,315評論 3 336
  • 文/蒙蒙 一赏半、第九天 我趴在偏房一處隱蔽的房頂上張望贺归。 院中可真熱鬧,春花似錦除破、人聲如沸牧氮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽踱葛。三九已至,卻和暖如春光坝,著一層夾襖步出監(jiān)牢的瞬間尸诽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評論 1 275
  • 我被黑心中介騙來泰國打工盯另, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留性含,地道東北人。 一個月前我還...
    沈念sama閱讀 49,431評論 3 379
  • 正文 我出身青樓鸳惯,卻偏偏與公主長得像商蕴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子芝发,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,982評論 2 361