什么是RabbitMQ
? MQ全稱為Message Queue, 消息隊(duì)列(MQ)是一種應(yīng)用程序?qū)?yīng)用程序的通信方法。MQ是消費(fèi)-生產(chǎn)者模型的一個(gè)典型的代表,一端往消息隊(duì)列中不斷寫入消息本股,而另一端則可以讀取隊(duì)列中的消息。
? RabbitMQ是MQ的一種。其是一個(gè)由erlang開發(fā)的AMQP(Advanved Message Queue)的開源實(shí)現(xiàn)。 AMQP的主要特征是面向消息寸宵、隊(duì)列、路由(包括點(diǎn)對(duì)點(diǎn)和發(fā)布/訂閱)元咙、可靠性梯影、安全。
1庶香、MQ應(yīng)用場(chǎng)景
- 異步處理
- 如用戶注冊(cè)后甲棍,需要發(fā)送注冊(cè)郵件和注冊(cè)短信。使用MQ后脉课,接口的響應(yīng)效率將大大提高。
- 應(yīng)用解耦
- 如用戶下單后财异,訂單系統(tǒng)需要通知庫(kù)存系統(tǒng) 倘零。使用MQ后,訂單系統(tǒng)寫入消息隊(duì)列就不再關(guān)心其他的后續(xù)操作了戳寸。實(shí)現(xiàn)訂單系統(tǒng)與庫(kù)存系統(tǒng)的應(yīng)用解耦 呈驶。
- 流量削峰
- 一般發(fā)生在短時(shí)間內(nèi)的大量請(qǐng)求,如秒殺疫鹊、團(tuán)搶活動(dòng)等袖瞻。使用MQ后,可以控制活動(dòng)的人數(shù) 拆吆,緩解短時(shí)間內(nèi)高流量壓垮應(yīng)用 聋迎。假如消息隊(duì)列長(zhǎng)度超過(guò)最大數(shù)量,則直接拋棄用戶請(qǐng)求或跳轉(zhuǎn)到錯(cuò)誤頁(yè)面枣耀。 秒殺業(yè)務(wù)根據(jù)消息隊(duì)列中的請(qǐng)求信息霉晕,再做后續(xù)處理 。
- 消息通訊
- 可以實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)消息隊(duì)列捞奕,或者聊天室等
- 日志處理
- 如Kafka的應(yīng)用牺堰,可解決大量日志傳輸?shù)膯?wèn)題
2、生產(chǎn)消費(fèi)消息模型
生產(chǎn)者:
? 消息發(fā)送者颅围,在MQ中被稱為生產(chǎn)者(producer)伟葫,一個(gè)發(fā)送消息的應(yīng)用也被叫做生產(chǎn)者,用P表示
消費(fèi)者:
? 生產(chǎn)者“生產(chǎn)”出消息后院促,最終由誰(shuí)消費(fèi)呢筏养?等待接受消息的應(yīng)用程序斧抱,我們稱之為消費(fèi)者(Consuming ),用C表示
消息模型:
? 消費(fèi)者(consumer)訂閱某個(gè)隊(duì)列撼玄。生產(chǎn)者(producer)創(chuàng)建消息夺姑,然后發(fā)布到隊(duì)列(queue)中,最后將消息發(fā)送到監(jiān)聽(tīng)的消費(fèi)者掌猛。
3盏浙、RabbitMQ 基本概念
- Broker: 接收和分發(fā)消息的應(yīng)用,RabbitMQ Server就是Message Broker荔茬。
- Virtual host: 出于多租戶和安全因素設(shè)計(jì)的废膘,把AMQP的基本組件劃分到一個(gè)虛擬的分組中,類似于網(wǎng)絡(luò)中的namespace概念慕蔚。當(dāng)多個(gè)不同的用戶使用同一個(gè)RabbitMQ server提供的服務(wù)時(shí)丐黄,可以劃分出多個(gè)vhost,每個(gè)用戶在自己的vhost創(chuàng)建exchange/queue等孔飒。
- Connection: publisher/consumer和broker之間的TCP連接灌闺。斷開連接的操作只會(huì)在client端進(jìn)行,Broker不會(huì)斷開連接坏瞄,除非出現(xiàn)網(wǎng)絡(luò)故障或broker服務(wù)出現(xiàn)問(wèn)題桂对。
- Channel: 如果每一次訪問(wèn)RabbitMQ都建立一個(gè)Connection,在消息量大的時(shí)候建立TCP Connection的開銷將是巨大的鸠匀,效率也較低蕉斜。Channel是在connection內(nèi)部建立的邏輯連接,如果應(yīng)用程序支持多線程缀棍,通常每個(gè)thread創(chuàng)建單獨(dú)的channel進(jìn)行通訊宅此,AMQP method包含了channel id幫助客戶端和message broker識(shí)別channel,所以channel之間是完全隔離的爬范。Channel作為輕量級(jí)的Connection極大減少了操作系統(tǒng)建立TCP connection的開銷父腕。
- Exchange: message到達(dá)broker的第一站,根據(jù)分發(fā)規(guī)則青瀑,匹配查詢表中的routing key侣诵,分發(fā)消息到queue中去。常用的類型有:direct (point-to-point), topic (publish-subscribe) and fanout (multicast)狱窘。
- Queue: 消息最終被送到這里等待consumer取走杜顺。一個(gè)message可以被同時(shí)拷貝到多個(gè)queue中。
- Binding: exchange和queue之間的虛擬連接蘸炸,binding中可以包含routing key躬络。Binding信息被保存到exchange中的查詢表中,用于message的分發(fā)依據(jù)搭儒。
生產(chǎn)者發(fā)送消息到broker server(RabbitMQ)穷当。在Broker內(nèi)部提茁,用戶創(chuàng)建Exchange/Queue,通過(guò)Binding規(guī)則將兩者聯(lián)系在一起馁菜。Exchange分發(fā)消息茴扁,根據(jù)類型/binding的不同分發(fā)策略有區(qū)別。消息最后來(lái)到Queue中汪疮,等待消費(fèi)者取走峭火。
4、Exchange Type
RabbitMQ常用的Exchange Type有三種:fanout智嚷、direct卖丸、topic。
- fanout:把所有發(fā)送到該Exchange的消息投遞到所有與它綁定的隊(duì)列中盏道。
- direct:把消息投遞到那些binding key與routing key完全匹配的隊(duì)列中稍浆。
- topic:將消息路由到binding key與routing key模式匹配的隊(duì)列中。
?
5猜嘱、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纯丸。
RabbitMQ中實(shí)現(xiàn)RPC的機(jī)制是:
- 客戶端發(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í)行失敗)
- 服務(wù)器端收到消息并處理
- 服務(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ù)處理