1 簡介
RabbitMQ是一個(gè)開源的AMQP實(shí)現(xiàn)劲藐,服務(wù)器端用Erlang語言編寫镶柱,支持多種客戶端摔癣,如:Python、Ruby襟交、.NET迈倍、Java、JMS捣域、C啼染、PHP、ActionScript焕梅、XMPP迹鹅、STOMP等,支持AJAX丘侠。用于在分布式系統(tǒng)中存儲(chǔ)轉(zhuǎn)發(fā)消息徒欣,在易用性、擴(kuò)展性蜗字、高可用性等方面表現(xiàn)不俗打肝。 且RabbitMQ是基于 AMQP
協(xié)議的,目前各個(gè)互聯(lián)網(wǎng)大廠都在使用RabbitMQ作為消息中間件挪捕。
附上官網(wǎng)地址: https://www.rabbitmq.com/
2 特點(diǎn)
2.1 核心特點(diǎn)
采用Erlang語言作為底層實(shí)現(xiàn):Erlang有著和原生Socket一樣的延遲
開源粗梭、性能優(yōu)秀,穩(wěn)定性保障
提供可靠性消息投遞模式(confirm)级零、返回模式( return )
與SpringAMQP完美的整合断医、API豐富
集群模式豐富滞乙,表達(dá)式配置,HA模式鉴嗤,鏡像隊(duì)列模型
保證數(shù)據(jù)不丟失的前提做到高可靠性斩启、可用性
高性能原因:
- Erlang語言最初在于交換機(jī)領(lǐng)域的架構(gòu)模式,這樣使得RabbitMQ在Broker之間進(jìn)行數(shù)據(jù)交互的性能非常優(yōu)秀
- Erlang有著和原生Socket一樣的延遲
2.2 專業(yè)術(shù)語
生產(chǎn)者(Producer):發(fā)送消息的應(yīng)用醉锅。
消費(fèi)者(Consumer):接收消息的應(yīng)用兔簇。
Server:又稱Broker,接受客戶端連接硬耍,實(shí)現(xiàn)AMQP實(shí)體服務(wù)
Connection:連接垄琐、應(yīng)用程序與Broker的網(wǎng)絡(luò)連接
Channel:網(wǎng)絡(luò)信道,幾乎所有的操作都在Channel中進(jìn)行经柴,Channel是進(jìn)行消息讀寫的通道狸窘。客戶端可建立多個(gè)Channel坯认,每個(gè)Channel代表一個(gè)會(huì)話任務(wù)
Message:消息翻擒,服務(wù)器和應(yīng)用程序之間傳送的數(shù)據(jù),由Properties和Body組成鹃操。Properties可以對(duì)消息進(jìn)行修飾韭寸,比如消息的優(yōu)先級(jí)春哨,延遲等高級(jí)特性荆隘;Body則就是消息體內(nèi)容
Virtual host:虛擬主機(jī),用于進(jìn)行邏輯隔離赴背,最上層的消息路由椰拒。一個(gè)Virtual host里面可以有若干個(gè)Exchange和Queue,同一個(gè)Virtual Host里面不能有相同名稱的Exchange或Queue
Exchange:交換機(jī)凰荚、接收消息燃观。根據(jù)路由鍵轉(zhuǎn)發(fā)消息到綁定的隊(duì)列
Binding:Exchange和Queue之間的虛擬連接,binding中可以包含routing key
Routing key:一個(gè)路由規(guī)則便瑟,虛擬機(jī)可用它確定如何路由一個(gè)特定消息
Queue:也稱Message Queue缆毁,消息隊(duì)列,保存消息并將它們轉(zhuǎn)發(fā)給消費(fèi)者
3 核心功能
3.1 AMQP
基礎(chǔ)模型
AMQP到涂,即Advanced Message Queuing Protocol脊框,一個(gè)提供統(tǒng)一消息服務(wù)的應(yīng)用層標(biāo)準(zhǔn)高級(jí)消息隊(duì)列協(xié)議,是應(yīng)用層協(xié)議的一個(gè)開放標(biāo)準(zhǔn)践啄,為面向消息的中間件設(shè)計(jì)浇雹。基于此協(xié)議的客戶端與消息中間件可傳遞消息屿讽,并不受客戶端/中間件不同產(chǎn)品昭灵,不同的開發(fā)語言等條件的限制。Erlang中的實(shí)現(xiàn)有RabbitMQ等。
它可以使對(duì)應(yīng)的客戶端(client)與對(duì)應(yīng)的消息中間件(broker)進(jìn)行交互烂完。消息中間件從發(fā)布者(publisher)那里收到消息(發(fā)布消息的應(yīng)用试疙,也稱為producer),然后將他們轉(zhuǎn)發(fā)給消費(fèi)者(consumers抠蚣,處理消息的應(yīng)用)效斑。由于AMQP是一個(gè)網(wǎng)絡(luò)協(xié)議,所以發(fā)布者柱徙、消費(fèi)者以及消息中間件可以部署到不同的物理機(jī)器上面缓屠。
雖然在同步消息通訊的世界里有很多公開標(biāo)準(zhǔn)(如 COBAR的 IIOP ,或者是 SOAP 等)护侮,但是在異步消息處理中卻不是這樣敌完,只有大企業(yè)有一些商業(yè)實(shí)現(xiàn)(如微軟的 MSMQ ,IBM 的 Websphere MQ 等)羊初,因此滨溉,在 2006 年的 6 月,Cisco 长赞、Redhat晦攒、iMatix 等聯(lián)合制定了 AMQP 的公開標(biāo)準(zhǔn)。
RabbitMQ是由RabbitMQ Technologies Ltd開發(fā)并且提供商業(yè)支持的得哆。該公司在2010年4月被SpringSource(VMWare的一個(gè)部門)收購脯颜。在2013年5月被并入Pivotal。其實(shí)VMWare贩据,Pivotal和EMC本質(zhì)上是一家的栋操。不同的是VMWare是獨(dú)立上市子公司,而Pivotal是整合了EMC的某些資源饱亮,現(xiàn)在并沒有上市矾芙。
3.2 基礎(chǔ)架構(gòu)
3.3 交換器
3.3.1 交換機(jī)屬性
Exchange
Type:交換機(jī)類型 direct、topic近上、fanout剔宪、headers
Durability:是否需要持久化 ,默認(rèn)為 true 表示持久化
Auto Delete:當(dāng)最后一個(gè)綁定到Exchange上的隊(duì)列刪除后壹无,自動(dòng)刪除該Exchange
Internal:當(dāng)前Exchange是否用于RabbitMQ內(nèi)部使用葱绒,默認(rèn)為False
Arguments:擴(kuò)展參數(shù),用于擴(kuò)展AMQP協(xié)議自制定化使用Name:交換機(jī)名稱
3.3.2 交換器類型
生產(chǎn)者發(fā)送消息到 RabbitMQ 的交換器上格遭。常用的交換器有四種:
fanout 哈街。會(huì)把所有發(fā)送到該交換器的消息路由到與該交換器綁定的消息隊(duì)列中。
Direct拒迅。會(huì)把消息路由到bingingKey 和RoutingKey 完全匹配的隊(duì)列中骚秦。
Topic她倘。Topic 類型的交換器哎在 direct 匹配規(guī)則上進(jìn)行了擴(kuò)展,不是進(jìn)行完全匹配作箍,而是進(jìn)行模糊匹配硬梁。匹配規(guī)則如下:BindingKey和RoutingKey一樣都是由"."分隔的字符串;BindingKey中可以存在兩種特殊字符“” 和 “#”胞得,用于模糊匹配荧止,其中""用于匹配一個(gè)單詞,"#"用于匹配多個(gè)單詞(可以是0個(gè))阶剑。
Headers 跃巡。Handers 類型的交換器不是根據(jù)路由匹配規(guī)則來的,而是根據(jù)消息中的 headers 屬性進(jìn)行匹配的牧愁。在綁定隊(duì)列和交換器時(shí)指定一組鍵值對(duì)素邪,當(dāng)發(fā)送的消息到交換器時(shí),RabbitMQ會(huì)獲取到該消息的headers猪半,對(duì)比其中的鍵值對(duì)是否完全匹配隊(duì)列和交換器綁定時(shí)指定的鍵值對(duì)兔朦,如果匹配,消息就會(huì)路由到該隊(duì)列磨确。headers類型的交換器性能很差沽甥,不實(shí)用。
3.4 消息流程
生產(chǎn)者(producer)把消息發(fā)送給交換機(jī)乏奥。創(chuàng)建交換機(jī)的時(shí)候指定上面的交換機(jī)類型摆舟。
交換機(jī)(exchange)接收消息并且負(fù)責(zé)對(duì)消息進(jìn)行路由。根據(jù)交換機(jī)的類型英融,消息的多個(gè)屬性會(huì)被使用盏檐,例如路由鍵歇式。
綁定(binding)需要從交換機(jī)到隊(duì)列的這種方式來進(jìn)行創(chuàng)建驶悟。在這個(gè)例子里,我們可以看到交換機(jī)有到兩個(gè)不同隊(duì)列的綁定材失。交換機(jī)根據(jù)消息的屬性來把消息分發(fā)到不同的隊(duì)列上痕鳍。
消息(message)消息會(huì)一直留在隊(duì)列里直到被消費(fèi)。
消費(fèi)者(consumer)處理消息龙巨。
3.5 數(shù)據(jù)存儲(chǔ)
RabbitMQ消息有持久化消息和非持久化消息笼呆。
持久化消息在到達(dá)隊(duì)列時(shí)寫入磁盤,同時(shí)在內(nèi)存中保存一份備份旨别,當(dāng)內(nèi)存不足時(shí)诗赌,消息從內(nèi)存中清除。
非持久化消息一般只存在內(nèi)存中秸弛,當(dāng)內(nèi)存不足時(shí)進(jìn)行數(shù)據(jù)的刷盤處理铭若。節(jié)省內(nèi)存空間洪碳。
RabbitMQ 存儲(chǔ)層包含兩部分,隊(duì)列索引和消息存儲(chǔ)叼屠。索引維護(hù)隊(duì)列的落盤消息的信息瞳腌,比如存儲(chǔ)地點(diǎn)、是否已經(jīng)被消費(fèi)者接收镜雨,是否已經(jīng)被消費(fèi)者ack等嫂侍,每個(gè)隊(duì)列都有相應(yīng)的索引。
索引使用順序的段文件來存儲(chǔ)荚坞,后綴為 .idx 挑宠,文件名從0開始累加,每個(gè)段文件中包含固定的記錄數(shù)颓影,默認(rèn)是16384 痹栖,每個(gè)index從磁盤中讀取消息的時(shí)候,都會(huì)在內(nèi)中中維護(hù)一段文件瞭空。
消息存儲(chǔ)揪阿。消息通過鍵值對(duì)的形式存儲(chǔ)到文件中,一個(gè)虛擬主機(jī)上的所有隊(duì)列使用同一塊存儲(chǔ)咆畏,每個(gè)接地那只有一個(gè)南捂。存儲(chǔ)分為:
持久化存儲(chǔ)。在broker 重啟后不會(huì)丟失旧找。
臨時(shí)存儲(chǔ)溺健。在broker 重啟后會(huì)丟失。
存儲(chǔ)方式為文件來存儲(chǔ)钮蛛,后綴為 .rdq 鞭缭。經(jīng)過store 處理的所有消息都會(huì)以追加的方式寫入到該文件中,當(dāng)文件達(dá)到指定容量時(shí)魏颓,會(huì)創(chuàng)建一個(gè)新的文件進(jìn)行寫入岭辣。
讀取消息時(shí),先根據(jù)消息的ID(msg_id)找到對(duì)應(yīng)存儲(chǔ)的文件甸饱,如果文件存在并且未被鎖住沦童,則直接打開文件,從指定位置讀取消息內(nèi)容叹话。如果文件不存在或者被鎖住了偷遗,則發(fā)送請(qǐng)求由store進(jìn)行處理。
刪除消息時(shí)驼壶,只是從ETS表刪除指定消息的相關(guān)信息氏豌,同時(shí)更新消息對(duì)應(yīng)的存儲(chǔ)文件和相關(guān)信息。在執(zhí)行消息刪除操作時(shí)热凹,并不立即對(duì)文件中的消息進(jìn)行刪除泵喘,也就是說消息依然在文件中瞭吃,僅僅是標(biāo)記為垃圾數(shù)據(jù)而已。當(dāng)一個(gè)文件中都是垃圾數(shù)據(jù)時(shí)可以將這個(gè)文件刪除涣旨。當(dāng)檢測(cè)到前后兩個(gè)文件中的有效數(shù)據(jù)可以合并成一個(gè)文件歪架,并且所有的垃圾數(shù)據(jù)的大小和所有文件(至少有3個(gè)文件存在的情況下)的數(shù)據(jù)大小的比值超過設(shè)置的閾值garbage_fraction(默認(rèn)值0.5)時(shí),才會(huì)觸發(fā)垃圾回收霹陡,將這兩個(gè)文件合并和蚪,執(zhí)行合并的兩個(gè)文件一定是邏輯上相鄰的兩個(gè)文件。
4 相關(guān)信息
- 博文不易烹棉,辛苦各位猿友點(diǎn)個(gè)關(guān)注和贊攒霹,感謝