MQ全稱為Message Queue, 是一種分布式應(yīng)用程序的的通信方法泣特,它是消費(fèi)-生產(chǎn)者模型的一個(gè)典型的代表咙边,producer往消息隊(duì)列中不斷寫入消息钧嘶,而另一端consumer則可以讀取或者訂閱隊(duì)列中的消息龟劲。RabbitMQ是MQ產(chǎn)品的典型代表炒嘲,是一款基于AMQP協(xié)議可復(fù)用的企業(yè)消息系統(tǒng)。業(yè)務(wù)上尝哆,可以實(shí)現(xiàn)服務(wù)提供者和消費(fèi)者之間的數(shù)據(jù)解耦秉撇,提供高可用性的消息傳輸機(jī)制,在實(shí)際生產(chǎn)中應(yīng)用相當(dāng)廣泛秋泄。本文意在介紹Rabbitmq的基本原理琐馆,包括rabbitmq基本框架,概念恒序,通信過程等瘦麸。
系統(tǒng)架構(gòu)
Rabbitmq系統(tǒng)最核心的組件是Exchange和Queue,下圖是系統(tǒng)簡單的示意圖歧胁。Exchange和Queue是在rabbitmq server(又叫做broker)端滋饲,producer和consumer在應(yīng)用端彤敛。
producer&Consumer
producer指的是消息生產(chǎn)者,consumer消息的消費(fèi)者了赌。
Queue
消息隊(duì)列墨榄,提供了FIFO的處理機(jī)制,具有緩存消息的能力勿她。rabbitmq中袄秩,隊(duì)列消息可以設(shè)置為持久化,臨時(shí)或者自動(dòng)刪除逢并。
設(shè)置為持久化的隊(duì)列之剧,queue中的消息會(huì)在server本地硬盤存儲(chǔ)一份,防止系統(tǒng)crash砍聊,數(shù)據(jù)丟失
設(shè)置為臨時(shí)隊(duì)列背稼,queue中的數(shù)據(jù)在系統(tǒng)重啟之后就會(huì)丟失
設(shè)置為自動(dòng)刪除的隊(duì)列,當(dāng)不存在用戶連接到server玻蝌,隊(duì)列中的數(shù)據(jù)會(huì)被自動(dòng)刪除
Exchange
Exchange類似于數(shù)據(jù)通信網(wǎng)絡(luò)中的交換機(jī)蟹肘,提供消息路由策略。rabbitmq中俯树,producer不是通過信道直接將消息發(fā)送給queue帘腹,而是先發(fā)送給Exchange。一個(gè)Exchange可以和多個(gè)Queue進(jìn)行綁定许饿,producer在傳遞消息的時(shí)候阳欲,會(huì)傳遞一個(gè)ROUTING_KEY,Exchange會(huì)根據(jù)這個(gè)ROUTING_KEY按照特定的路由算法陋率,將消息路由給指定的queue球化。和Queue一樣,Exchange也可設(shè)置為持久化瓦糟,臨時(shí)或者自動(dòng)刪除筒愚。
Exchange有4種類型:direct(默認(rèn)),fanout, topic, 和headers狸页,不同類型的Exchange轉(zhuǎn)發(fā)消息的策略有所區(qū)別:
Direct直接交換器锨能,工作方式類似于單播,Exchange會(huì)將消息發(fā)送完全匹配ROUTING_KEY的Queue
fanout廣播是式交換器芍耘,不管消息的ROUTING_KEY設(shè)置為什么,Exchange都會(huì)將消息轉(zhuǎn)發(fā)給所有綁定的Queue熄阻。
topic主題交換器斋竞,工作方式類似于組播,Exchange會(huì)將消息轉(zhuǎn)發(fā)和ROUTING_KEY匹配模式相同的所有隊(duì)列秃殉,比如坝初,ROUTING_KEY為user.stock的Message會(huì)轉(zhuǎn)發(fā)給綁定匹配模式為 * .stock,user.stock浸剩, * . * 和#.user.stock.#的隊(duì)列。( * 表是匹配一個(gè)任意詞組鳄袍,#表示匹配0個(gè)或多個(gè)詞組)
headers消息體的header匹配(ignore)
Binding
所謂綁定就是將一個(gè)特定的 Exchange 和一個(gè)特定的 Queue 綁定起來绢要。Exchange 和Queue的綁定可以是多對多的關(guān)系。
virtual host
在rabbitmq server上可以創(chuàng)建多個(gè)虛擬的message broker拗小,又叫做virtual hosts (vhosts)重罪。每一個(gè)vhost本質(zhì)上是一個(gè)mini-rabbitmq server,分別管理各自的exchange哀九,和bindings剿配。vhost相當(dāng)于物理的server,可以為不同app提供邊界隔離阅束,使得應(yīng)用安全的運(yùn)行在不同的vhost實(shí)例上呼胚,相互之間不會(huì)干擾。producer和consumer連接rabbit server需要指定一個(gè)vhost息裸。
通信過程
假設(shè)P1和C1注冊了相同的Broker蝇更,Exchange和Queue。P1發(fā)送的消息最終會(huì)被C1消費(fèi)呼盆〔炯牛基本的通信流程大概如下所示:
P1生產(chǎn)消息,發(fā)送給服務(wù)器端的Exchange
Exchange收到消息宿亡,根據(jù)ROUTINKEY常遂,將消息轉(zhuǎn)發(fā)給匹配的Queue1
Queue1收到消息,將消息發(fā)送給訂閱者C1
C1收到消息挽荠,發(fā)送ACK給隊(duì)列確認(rèn)收到消息
Queue1收到ACK克胳,刪除隊(duì)列中緩存的此條消息
Consumer收到消息時(shí)需要顯式的向rabbit broker發(fā)送basic.ack消息或者consumer訂閱消息時(shí)設(shè)置auto_ack參數(shù)為true。在通信過程中圈匆,隊(duì)列對ACK的處理有以下幾種情況:
如果consumer接收了消息漠另,發(fā)送ack,rabbitmq會(huì)刪除隊(duì)列中這個(gè)消息,發(fā)送另一條消息給consumer跃赚。
如果cosumer接受了消息, 但在發(fā)送ack之前斷開連接笆搓,rabbitmq會(huì)認(rèn)為這條消息沒有被deliver,在consumer在次連接的時(shí)候,這條消息會(huì)被redeliver纬傲。
如果consumer接受了消息满败,但是程序中有bug,忘記了ack,rabbitmq不會(huì)重復(fù)發(fā)送消息。
rabbitmq2.0.0和之后的版本支持consumer reject某條(類)消息叹括,可以通過設(shè)置requeue參數(shù)中的reject為true達(dá)到目地算墨,那么rabbitmq將會(huì)把消息發(fā)送給下一個(gè)注冊的consumer。
Conclusion
本文和大家一起學(xué)習(xí)了rabbitmq的一些基礎(chǔ)知識(shí)汁雷,在之后的博文中净嘀,筆者將會(huì)和大家一起分享更多的Rabbitmq知識(shí)
RabbitMQ