RabbitMQ基礎(chǔ)概念詳細(xì)介紹

AMQP簡(jiǎn)介

AMQP吆玖,即 Advanced Message Queuing Protocol,高級(jí)消息隊(duì)列協(xié)議,是應(yīng)用層協(xié)議的一個(gè)開放標(biāo)準(zhǔn)碌嘀,為面向消息的中間件設(shè)計(jì)。消息中間件主要用于組件之間的解耦和通訊虱而。

AMQP的主要特征是面向消息筏餐、隊(duì)列、路由(包括點(diǎn)對(duì)點(diǎn)和發(fā)布/訂閱)牡拇、可靠性魁瞪、安全。

RabbitMQ是一個(gè)開源的AMQP實(shí)現(xiàn)惠呼,服務(wù)器端用 Erlang 語(yǔ)言編寫导俘,支持多種客戶端,如:Python剔蹋、Ruby旅薄、.NET、Java泣崩、JMS少梁、C、PHP矫付、ActionScript凯沪、XMPP、STOMP等买优,支持AJAX妨马。用于在分布式系統(tǒng)中存儲(chǔ)轉(zhuǎn)發(fā)消息,具有很高的易用性和可用性杀赢。

安裝部署

安裝部署請(qǐng)參考Docker 安裝部署RabbitMQ

AMQP協(xié)議中的幾個(gè)重要概念

ConnectionFactory烘跺、Connection、Channel

ConnectionFactory脂崔、Connection滤淳、Channel都是RabbitMQ對(duì)外提供的API中最基本的對(duì)象。

  • ConnectionFactory:ConnectionFactory為Connection的制造工廠砌左。
  • Connection:Connection是RabbitMQ的socket鏈接娇钱,它封裝了socket協(xié)議相關(guān)部分邏輯伤柄。
  • Channel(信道):信道是建立在“真實(shí)的”TCP連接上的虛擬連接,在一條TCP鏈接上創(chuàng)建多少條信道是沒(méi)有限制的文搂,把他想象成光纖就是可以了适刀。它是我們與RabbitMQ打交道的最重要的一個(gè)接口,我們大部分的業(yè)務(wù)操作是在Channel這個(gè)接口中完成的煤蹭,包括定義Queue笔喉、定義Exchange、綁定Queue與Exchange硝皂、發(fā)布消息等常挚。

Queue(隊(duì)列)

Queue 是 RabbitMQ 的內(nèi)部對(duì)象,用于存儲(chǔ)消息稽物。


image.png

RabbitMQ中的消息只能存儲(chǔ)在 Queue 中奄毡。生產(chǎn)者(下圖中的P)生產(chǎn)消息并最終投遞到Queue中,消費(fèi)者(下圖中的C)可以從Queue中獲取消息并消費(fèi)贝或,消費(fèi)者可以是一個(gè)或者多個(gè)吼过。


隊(duì)列

Message acknowledgment(ack 消息的確認(rèn)):

在實(shí)際應(yīng)用中,可能會(huì)發(fā)生消費(fèi)者收到Queue中的消息咪奖,但沒(méi)有處理完成就宕機(jī)(或出現(xiàn)其他意外)的情況盗忱,這種情況下就可能會(huì)導(dǎo)致消息丟失。為了避免這種情況發(fā)生羊赵,我們可以要求消費(fèi)者在消費(fèi)完消息后發(fā)送一個(gè)回執(zhí)給RabbitMQ趟佃,RabbitMQ收到消息回執(zhí)(ack)后才將該消息從Queue中移除;如果RabbitMQ沒(méi)有收到回執(zhí)并檢測(cè)到消費(fèi)者的RabbitMQ連接斷開昧捷,則RabbitMQ會(huì)將該消息發(fā)送給其他消費(fèi)者(如果存在多個(gè)消費(fèi)者)進(jìn)行處理闲昭。這里不存在timeout概念,一個(gè)消費(fèi)者處理消息時(shí)間再長(zhǎng)也不會(huì)導(dǎo)致該消息被發(fā)送給其他消費(fèi)者靡挥,除非它的RabbitMQ連接斷開序矩。

這里會(huì)產(chǎn)生另外一個(gè)問(wèn)題,如果我們的開發(fā)人員在處理完業(yè)務(wù)邏輯后芹血,忘記發(fā)送回執(zhí)給RabbitMQ贮泞,這將會(huì)導(dǎo)致嚴(yán)重的bug——Queue中堆積的消息會(huì)越來(lái)越多楞慈;消費(fèi)者重啟后會(huì)重復(fù)消費(fèi)這些消息并重復(fù)執(zhí)行業(yè)務(wù)邏輯…

另外pub message是沒(méi)有ack的幔烛。

Message durability(消息的持久化)

如果我們希望即使在RabbitMQ服務(wù)重啟的情況下,也不會(huì)丟失消息囊蓝,我們可以將Queue與Message都設(shè)置為可持久化的(durable)饿悬,這樣可以保證絕大部分情況下我們的RabbitMQ消息不會(huì)丟失。但依然解決不了小概率丟失事件的發(fā)生(比如RabbitMQ服務(wù)器已經(jīng)接收到生產(chǎn)者的消息聚霜,但還沒(méi)來(lái)得及持久化該消息時(shí)RabbitMQ服務(wù)器就斷電了)狡恬,如果我們需要對(duì)這種小概率事件也要管理起來(lái)珠叔,那么我們要用到事務(wù)。由于這里僅為RabbitMQ的簡(jiǎn)單介紹弟劲,所以這里將不講解RabbitMQ相關(guān)的事務(wù)祷安。具體可以參考 RabbitMQ之消息確認(rèn)機(jī)制(事務(wù)+Confirm)

Prefetch count(每次向消費(fèi)者發(fā)送消息的總數(shù))

前面我們講到如果有多個(gè)消費(fèi)者同時(shí)訂閱同一個(gè)Queue中的消息,Queue中的消息會(huì)被平攤給多個(gè)消費(fèi)者兔乞。這時(shí)如果每個(gè)消息的處理時(shí)間不同汇鞭,就有可能會(huì)導(dǎo)致某些消費(fèi)者一直在忙,而另外一些消費(fèi)者很快就處理完手頭工作并一直空閑的情況庸追。我們可以通過(guò)設(shè)置prefetchCount來(lái)限制Queue每次發(fā)送給每個(gè)消費(fèi)者的消息數(shù)霍骄,比如我們?cè)O(shè)置prefetchCount=1,則Queue每次給每個(gè)消費(fèi)者發(fā)送一條消息淡溯;消費(fèi)者處理完這條消息后Queue會(huì)再給該消費(fèi)者發(fā)送一條消息读整。

image.png

Exchange(交換器)

Exchange生產(chǎn)者將消息發(fā)送到 Exchange(交換器,下圖中的X)咱娶,由 Exchange 根據(jù)一定的規(guī)則將消息路由到一個(gè)或多個(gè) Queue 中(或者丟棄)米间。

image.png

Routing key(路由key)

生產(chǎn)者在將消息發(fā)送給 Exchange 的時(shí)候,一般會(huì)指定一個(gè) routing key豺总,來(lái)指定這個(gè)消息的路由規(guī)則车伞。 Exchange 會(huì)根據(jù) routing key 和 Exchange Type(交換器類型) 以及 Binding key 的匹配情況來(lái)決定把消息路由到哪個(gè) Queue。RabbitMQ為routing key設(shè)定的長(zhǎng)度限制為255 bytes喻喳。

Binding(綁定)

RabbitMQ中通過(guò) Binding 將 Exchange 與 Queue 關(guān)聯(lián)起來(lái)另玖。


image.png

Binding key

在綁定(Binding) Exchange 與 Queue 關(guān)系的同時(shí),一般會(huì)指定一個(gè) binding key表伦。

Exchange Types (交換器類型)

RabbitMQ常用的Exchange Type有 Fanout谦去、 Direct、 Topic蹦哼、 Headers 這四種鳄哭。

  • Fanout
    這種類型的Exchange路由規(guī)則非常簡(jiǎn)單,它會(huì)把所有發(fā)送到該Exchange的消息路由到所有與它綁定的Queue中纲熏,這時(shí) Routing key 不起作用妆丘。


    image.png
  • Direct
    這種類型的Exchange路由規(guī)則也很簡(jiǎn)單,它會(huì)把消息路由到那些 binding key 與 routing key完全匹配的Queue中局劲。


    image.png

在這個(gè)設(shè)置中勺拣,我們可以看到兩個(gè)隊(duì)列Q1、Q2直接綁定到了交換器X上鱼填。 第一個(gè)隊(duì)列用綁定key橙色(orange)綁定药有,第二個(gè)隊(duì)列有兩個(gè)綁定,一個(gè)綁定key為黑色(black),另一個(gè)為綠色(green)愤惰。

在這種設(shè)置中苇经,通過(guò)路由鍵橙色發(fā)布到交換器的消息將被路由到隊(duì)列Q1。 帶有黑色或綠色的路由鍵的消息將進(jìn)入Q2宦言。 所有其他消息將被丟棄扇单。

image.png

在上面列子中,routingKey=”error”的消息發(fā)送Exchange后奠旺,Exchange會(huì)將消息路由到Queue1(amqp.gen-S9b…令花,這是由RabbitMQ自動(dòng)生成的Queue名稱)和Queue2(amqp.gen-Agl…);如果routingKey=”info”或routingKey=”warning”的消息發(fā)到Exchange凉倚,Exchange只會(huì)將消息路由到Queue2兼都。 所有其他消息將被丟棄。

  • Topic
    這種類型的Exchange的路由規(guī)則支持 binding key 和 routing key 的模糊匹配稽寒,會(huì)把消息路由到滿足條件的Queue扮碧。 binding key 中可以存在兩種特殊字符 *與 #,用于做模糊匹配杏糙,其中 * 用于匹配一個(gè)單詞慎王,# 用于匹配0個(gè)或多個(gè)單詞,單詞以符號(hào)“.”為分隔符宏侍。
image.png

以上圖中的配置為例赖淤,routingKey=”quick.orange.rabbit”的消息會(huì)同時(shí)路由到Q1與Q2,routingKey=”lazy.orange.fox”的消息會(huì)路由到Q1與Q2谅河,routingKey=”lazy.brown.fox”的消息會(huì)路由到Q2咱旱,routingKey=”lazy.pink.rabbit”的消息會(huì)路由到Q2(只會(huì)投遞給Q2一次,雖然這個(gè)routingKey與Q2的兩個(gè)bindingKey都匹配)绷耍;routingKey=”quick.brown.fox”吐限、routingKey=”orange”、routingKey=”quick.orange.male.rabbit”的消息將會(huì)被丟棄褂始,因?yàn)樗鼈儧](méi)有匹配任何bindingKey诸典。

  • Headers
    這種類型的Exchange不依賴于 routing key 與 binding key 的匹配規(guī)則來(lái)路由消息,而是根據(jù)發(fā)送的消息內(nèi)容中的 headers 屬性進(jìn)行匹配崎苗。

RPC

MQ本身是基于異步的消息處理狐粱,前面的示例中所有的生產(chǎn)者(P)將消息發(fā)送到RabbitMQ后不會(huì)知道消費(fèi)者(C)處理成功或者失敗(甚至連有沒(méi)有消費(fèi)者來(lái)處理這條消息都不知道)胆数。
但實(shí)際的應(yīng)用場(chǎng)景中肌蜻,我們很可能需要一些同步處理,需要同步等待服務(wù)端將我的消息處理完成后再進(jìn)行下一步處理幅慌。這相當(dāng)于RPC(Remote Procedure Call宋欺,遠(yuǎn)程過(guò)程調(diào)用)轰豆。在RabbitMQ中也支持RPC胰伍。


image.png

RabbitMQ中實(shí)現(xiàn)RPC的機(jī)制是:

  1. 客戶端發(fā)送請(qǐng)求(消息)時(shí)齿诞,在消息的屬性中(MessageProperties,在AMQP協(xié)議中定義了14中properties骂租,這些屬性會(huì)隨著消息一起發(fā)送)設(shè)置兩個(gè)值replyTo(一個(gè)Queue名稱祷杈,用于告訴服務(wù)器處理完成后將通知我的消息發(fā)送到這個(gè)Queue中)和correlationId(此次請(qǐng)求的標(biāo)識(shí)號(hào),服務(wù)器處理完成后需要將此屬性返還渗饮,客戶端將根據(jù)這個(gè)id了解哪條請(qǐng)求被成功執(zhí)行了或執(zhí)行失數)
  2. 服務(wù)器端收到消息并處理
  3. 服務(wù)器端處理完消息后,將生成一條應(yīng)答消息到replyTo指定的Queue互站,同時(shí)帶上correlationId屬性
    客戶端之前已訂閱replyTo指定的Queue私蕾,從中收到服務(wù)器的應(yīng)答消息后,根據(jù)其中的correlationId屬性分析哪條請(qǐng)求被執(zhí)行了胡桃,根據(jù)執(zhí)行結(jié)果進(jìn)行后續(xù)業(yè)務(wù)處理

參考:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末踩叭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子翠胰,更是在濱河造成了極大的恐慌容贝,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件之景,死亡現(xiàn)場(chǎng)離奇詭異斤富,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)锻狗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門满力,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人轻纪,你說(shuō)我怎么就攤上這事脚囊。” “怎么了桐磁?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵悔耘,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我我擂,道長(zhǎng)衬以,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任校摩,我火速辦了婚禮看峻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘衙吩。我一直安慰自己互妓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冯勉,像睡著了一般澈蚌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上灼狰,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天宛瞄,我揣著相機(jī)與錄音,去河邊找鬼交胚。 笑死份汗,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蝴簇。 我是一名探鬼主播杯活,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼熬词!你這毒婦竟也來(lái)了轩猩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤荡澎,失蹤者是張志新(化名)和其女友劉穎均践,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摩幔,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡彤委,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了或衡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片焦影。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情救氯,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布彬呻,位于F島的核電站,受9級(jí)特大地震影響柄瑰,放射性物質(zhì)發(fā)生泄漏闸氮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一教沾、第九天 我趴在偏房一處隱蔽的房頂上張望蒲跨。 院中可真熱鬧,春花似錦授翻、人聲如沸或悲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)巡语。三九已至翎蹈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捌臊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工兜材, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留理澎,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓曙寡,卻偏偏與公主長(zhǎng)得像糠爬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子举庶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容