日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

RabbitMq--1

發(fā)布時(shí)間:2024/9/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RabbitMq--1 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

RabbitMQ是什么

定義

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)不俗。

AMPQ

AMQP,即Advanced Message Queuing Protocol,高級(jí)消息隊(duì)列協(xié)議,是應(yīng)用層協(xié)議的一個(gè)開放標(biāo)準(zhǔn),為面向消息的中間件設(shè)計(jì)。消息中間件主要用于組件之間的解耦,消息的發(fā)送者無需知道消息使用者的存在,反之亦然。

它可以使對(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ī)器上面。

?

RabbitMQ為何會(huì)出現(xiàn)

或者說AMPQ為何會(huì)出現(xiàn),它的應(yīng)用場(chǎng)景又是什么?

解決什么問題

你是否遇到過兩個(gè)(多個(gè))系統(tǒng)間需要通過定時(shí)任務(wù)來同步某些數(shù)據(jù)?你是否在為異構(gòu)系統(tǒng)的不同進(jìn)程間相互調(diào)用、通訊的問題而苦惱、掙扎?

在Web應(yīng)用高并發(fā)環(huán)境下,由于來不及同步處理,請(qǐng)求往往會(huì)發(fā)生堵塞。比如說,大量的insert、update請(qǐng)求同時(shí)到達(dá)mysql,會(huì)帶來無數(shù)的行鎖表鎖,最后導(dǎo)致請(qǐng)求數(shù)過多,觸發(fā)too many connections錯(cuò)誤。

消息服務(wù)擅長(zhǎng)于解決多系統(tǒng)、異構(gòu)系統(tǒng)間的數(shù)據(jù)交換(消息通知/通訊)問題,你也可以把它用于系統(tǒng)間服務(wù)的相互調(diào)用(RPC)通過使用消息隊(duì)列,我們可以異步處理請(qǐng)求,從而緩解系統(tǒng)的壓力。

應(yīng)用場(chǎng)景

對(duì)于一個(gè)大型的軟件系統(tǒng)來說,它會(huì)有很多的組件或者說模塊或者說子系統(tǒng)或者(Subsystem or Component or Submodule)。那么這些模塊的如何通信?這和傳統(tǒng)的IPC有很大的區(qū)別。傳統(tǒng)的IPC很多都是在單一系統(tǒng)上的,模塊耦合性很大,不適合擴(kuò)展(Scalability);如果使用socket那么不同的模塊的確可以部署到不同的機(jī)器上,但是還是有很多問題需要解決。比如:

1.信息的發(fā)送者和接收者如何維持這個(gè)連接,如果一方的連接中斷,這期間的數(shù)據(jù)如何方式丟失?

2.如何降低發(fā)送者和接收者的耦合度?

3.如何讓Priority高的接收者先接到數(shù)據(jù)?

4.如何做到Load balance?有效均衡接收者的負(fù)載?

5.如何有效的將數(shù)據(jù)發(fā)送到相關(guān)的接收者?也就是說將接收者subscribe 不同的數(shù)據(jù),如何做有效的filter。

6.如何做到可擴(kuò)展,甚至將這個(gè)通信模塊發(fā)到cluster上?

7.如何保證接收者接收到了完整,正確的數(shù)據(jù)?

AMDQ協(xié)議解決了以上的問題,而RabbitMQ實(shí)現(xiàn)了AMQP。

RabbitMQ基礎(chǔ)概念

應(yīng)用場(chǎng)景架構(gòu)

RabbitMQ Server:也叫broker server,它不是運(yùn)送食物的卡車,而是一種傳輸服務(wù)。原話是RabbitMQ isn’t a food truck, it’s a delivery service. 他的角色就是維護(hù)一條從Producer到Consumer的路線,保證數(shù)據(jù)能夠按照指定的方式進(jìn)行傳輸。但是這個(gè)保證也不是100%的保證,但是對(duì)于普通的應(yīng)用來說這已經(jīng)足夠了。當(dāng)然對(duì)于商業(yè)系統(tǒng)來說,可以再做一層數(shù)據(jù)一致性的guard,就可以徹底保證系統(tǒng)的一致性了。

Client A & B:也叫Producer,數(shù)據(jù)的發(fā)送方。Create messages and Publish (Send) them to a broker server (RabbitMQ)。一個(gè)Message有兩個(gè)部分:Payload(有效載荷)和Label(標(biāo)簽)。Payload顧名思義就是傳輸?shù)臄?shù)據(jù),Label是Exchange的名字或者說是一個(gè)tag,它描述了payload,而且RabbitMQ也是通過這個(gè)label來決定把這個(gè)Message發(fā)給哪個(gè)Consumer。AMQP僅僅描述了label,而RabbitMQ決定了如何使用這個(gè)label的規(guī)則。

Client 1,2,3:也叫Consumer,數(shù)據(jù)的接收方。Consumers attach to a broker server (RabbitMQ) and subscribe to a queue。把queue比作是一個(gè)有名字的郵箱。當(dāng)有Message到達(dá)某個(gè)郵箱后,RabbitMQ把它發(fā)送給它的某個(gè)訂閱者即Consumer。當(dāng)然可能會(huì)把同一個(gè)Message發(fā)送給很多的Consumer。在這個(gè)Message中,只有payload,label已經(jīng)被刪掉了。對(duì)于Consumer來說,它是不知道誰發(fā)送的這個(gè)信息的。就是協(xié)議本身不支持。但是當(dāng)然了如果Producer發(fā)送的payload包含了Producer的信息就另當(dāng)別論了。

對(duì)于一個(gè)數(shù)據(jù)從Producer到Consumer的正確傳遞,還有三個(gè)概念需要明確:exchanges, queues and bindings。

Exchanges are where producers publish their messages. 消息交換機(jī),它指定消息按什么規(guī)則,路由到哪個(gè)隊(duì)列

Queues are where the messages end up and are received by consumers. 消息隊(duì)列載體,每個(gè)消息都會(huì)被投入到一個(gè)或多個(gè)隊(duì)列

Bindings are how the messages get routed from the exchange to particular queues. 綁定,它的作用就是把exchange和queue按照路由規(guī)則綁定起來

Routing Key:路由關(guān)鍵字,exchange根據(jù)這個(gè)關(guān)鍵字進(jìn)行消息投遞

還有幾個(gè)概念是上述圖中沒有標(biāo)明的,那就是Connection(連接),Channel(通道,頻道),Vhost(虛擬主機(jī))。

Connection:就是一個(gè)TCP的連接。Producer和Consumer都是通過TCP連接到RabbitMQ Server的。以后我們可以看到,程序的起始處就是建立這個(gè)TCP連接。

Channel:虛擬連接。它建立在上述的TCP連接中。數(shù)據(jù)流動(dòng)都是在Channel中進(jìn)行的。也就是說,一般情況是程序起始建立TCP連接,第二步就是建立這個(gè)Channel。

Vhost:虛擬主機(jī),一個(gè)broker里可以開設(shè)多個(gè)vhost,用作不同用戶的權(quán)限分離。每個(gè)virtual host本質(zhì)上都是一個(gè)RabbitMQ Server,擁有它自己的queue,exchagne,和bings rule等等。這保證了你可以在多個(gè)不同的application中使用RabbitMQ。

Channel的選擇

那么,為什么使用Channel,而不是直接使用TCP連接?

對(duì)于OS來說,建立和關(guān)閉TCP連接是有代價(jià)的,頻繁的建立關(guān)閉TCP連接對(duì)于系統(tǒng)的性能有很大的影響,而且TCP的連接數(shù)也有限制,這也限制了系統(tǒng)處理高并發(fā)的能力。但是,在TCP連接中建立Channel是沒有上述代價(jià)的。對(duì)于Producer或者Consumer來說,可以并發(fā)的使用多個(gè)Channel進(jìn)行Publish或者Receive。

有實(shí)驗(yàn)表明,1s的數(shù)據(jù)可以Publish10K的數(shù)據(jù)包。當(dāng)然對(duì)于不同的硬件環(huán)境,不同的數(shù)據(jù)包大小這個(gè)數(shù)據(jù)肯定不一樣,但是我只想說明,對(duì)于普通的Consumer或者Producer來說,這已經(jīng)足夠了。如果不夠用,你考慮的應(yīng)該是如何細(xì)化split你的設(shè)計(jì)。

消息隊(duì)列執(zhí)行過程

1.客戶端連接到消息隊(duì)列服務(wù)器,打開一個(gè)Channel。

2.客戶端聲明一個(gè)Exchange,并設(shè)置相關(guān)屬性。

3.客戶端聲明一個(gè)Queue,并設(shè)置相關(guān)屬性。

4.客戶端使用Routing key,在Exchange和Queue之間建立好綁定關(guān)系。

5.客戶端投遞消息到Exchange。

Exchange接收到消息后,就根據(jù)消息的key和已經(jīng)設(shè)置的Binding,進(jìn)行消息路由,將消息投遞到一個(gè)或多個(gè)隊(duì)列里。有三種常用類型的Exchanges:direct,fanout,topic,每個(gè)實(shí)現(xiàn)了不同的路由算法(routing algorithm):

Direct exchange:完全根據(jù)key進(jìn)行投遞的叫做Direct交換機(jī)。如果Routing key匹配, 那么Message就會(huì)被傳遞到相應(yīng)的queue中。其實(shí)在queue創(chuàng)建時(shí),它會(huì)自動(dòng)的以queue的名字作為routing key來綁定那個(gè)exchange。例如,綁定時(shí)設(shè)置了Routing key為”abc”,那么客戶端提交的消息,只有設(shè)置了key為”abc”的才會(huì)投遞到隊(duì)列。

Fanout exchange:不需要key的叫做Fanout交換機(jī)。它采取廣播模式,一個(gè)消息進(jìn)來時(shí),投遞到與該交換機(jī)綁定的所有隊(duì)列。

Topic exchange:對(duì)key進(jìn)行模式匹配后進(jìn)行投遞的叫做Topic交換機(jī)。比如符號(hào)”#”匹配一個(gè)或多個(gè)詞,符號(hào)”*”匹配正好一個(gè)詞。例如”abc.#”匹配”abc.def.ghi”,”abc.*”只匹配”abc.def”,不能匹配“abc.def.ina”。

更多消息隊(duì)列相關(guān)設(shè)計(jì)介紹請(qǐng)參考:

RabbitMQ系列二(構(gòu)建消息隊(duì)列)

RabbitMQ系列三 (深入消息隊(duì)列)

消息隊(duì)列的創(chuàng)建

Consumer和Procuder都可以通過 queue.declare 創(chuàng)建queue。對(duì)于某個(gè)Channel來說,Consumer不能declare一個(gè)queue,卻訂閱其他的queue。當(dāng)然也可以創(chuàng)建私有的queue。這樣只有app本身才可以使用這個(gè)queue。queue也可以自動(dòng)刪除,被標(biāo)為auto-delete的queue在最后一個(gè)Consumer unsubscribe后就會(huì)被自動(dòng)刪除。那么如果是創(chuàng)建一個(gè)已經(jīng)存在的queue呢?那么不會(huì)有任何的影響。需要注意的是沒有任何的影響,也就是說第二次創(chuàng)建如果參數(shù)和第一次不一樣,那么該操作雖然成功,但是queue的屬性并不會(huì)被修改。

那么誰應(yīng)該負(fù)責(zé)創(chuàng)建這個(gè)queue呢?是Consumer,還是Producer?

如果queue不存在,當(dāng)然Consumer不會(huì)得到任何的Message。但是如果queue不存在,那么Producer Publish的Message會(huì)被丟棄。所以,還是為了數(shù)據(jù)不丟失,Consumer和Producer都try to create the queue!反正不管怎么樣,這個(gè)接口都不會(huì)出問題。

Queue對(duì)load balance的處理是完美的。對(duì)于多個(gè)Consumer來說,RabbitMQ 使用循環(huán)的方式(round-robin)的方式均衡的發(fā)送給不同的Consumer。

消息的ack機(jī)制

默認(rèn)情況下,如果Message 已經(jīng)被某個(gè)Consumer正確的接收到了,那么該Message就會(huì)被從queue中移除。當(dāng)然也可以讓同一個(gè)Message發(fā)送到很多的Consumer。

如果一個(gè)queue沒被任何的Consumer Subscribe(訂閱),那么,如果這個(gè)queue有數(shù)據(jù)到達(dá),那么這個(gè)數(shù)據(jù)會(huì)被cache,不會(huì)被丟棄。當(dāng)有Consumer時(shí),這個(gè)數(shù)據(jù)會(huì)被立即發(fā)送到這個(gè)Consumer,這個(gè)數(shù)據(jù)被Consumer正確收到時(shí),這個(gè)數(shù)據(jù)就被從queue中刪除。

那么什么是正確收到呢?通過ack。

每個(gè)Message都要被acknowledged(確認(rèn),ack)。我們可以顯示的在程序中去ack(Consumer的basic.ack),也可以自動(dòng)的ack(訂閱Queue時(shí)指定auto_ack為true)。

如果有數(shù)據(jù)沒有被ack,那么RabbitMQ Server會(huì)把這個(gè)信息發(fā)送到下一個(gè)Consumer。

如果這個(gè)app有bug,忘記了ack,那么RabbitMQ Server不會(huì)再發(fā)送數(shù)據(jù)給它,因?yàn)镾erver認(rèn)為這個(gè)Consumer處理能力有限。

而且ack的機(jī)制可以起到限流的作用(Benefit to throttling):在Consumer處理完成數(shù)據(jù)后發(fā)送ack,甚至在額外的延時(shí)后發(fā)送ack,將有效的balance Consumer的load。

當(dāng)然對(duì)于實(shí)際的例子,比如我們可能會(huì)對(duì)某些數(shù)據(jù)進(jìn)行merge,比如merge 4s內(nèi)的數(shù)據(jù),然后sleep 4s后再獲取數(shù)據(jù)。特別是在監(jiān)聽系統(tǒng)的state,我們不希望所有的state實(shí)時(shí)的傳遞上去,而是希望有一定的延時(shí)。這樣可以減少某些IO,而且終端用戶也不會(huì)感覺到。

沒有正確響應(yīng)呢?

如果Consumer接收了一個(gè)消息就還沒有發(fā)送ack就與RabbitMQ斷開了,RabbitMQ會(huì)認(rèn)為這條消息沒有投遞成功會(huì)重新投遞到別的Consumer。

如果Consumer本身邏輯有問題沒有發(fā)送ack的處理,RabbitMQ不會(huì)再向該Consumer發(fā)送消息。RabbitMQ會(huì)認(rèn)為這個(gè)Consumer還沒有處理完上一條消息,沒有能力繼續(xù)接收新消息。

我們可以善加利用這一機(jī)制,如果需要處理過程是相當(dāng)復(fù)雜的,應(yīng)用程序可以延遲發(fā)送ack直到處理完成為止。這可以有效控制應(yīng)用程序這邊的負(fù)載,不致于被大量消息沖擊。

消息拒絕

由于要拒絕消息,所以ack響應(yīng)消息還沒有發(fā)出,這里拒絕消息可以有兩種選擇:

Consumer直接斷開RabbitMQ這樣RabbitMQ將把這條消息重新排隊(duì),交由其它Consumer處理。這個(gè)方法在RabbitMQ各版本都支持,這樣做的壞處就是連接斷開增加了RabbitMQ的額外負(fù)擔(dān),特別是consumer出現(xiàn)異常每條消息都無法正常處理的時(shí)候。

RabbitMQ 2.0.0可以使用 basic.reject 命令,收到該命令RabbitMQ會(huì)重新投遞到其它的Consumer。如果設(shè)置requeue為false,RabbitMQ會(huì)直接將消息從queue中移除。

其實(shí)還有一種選擇就是直接忽略這條消息并發(fā)送ACK,當(dāng)你明確知道這條消息是異常的不會(huì)有Consumer能處理,可以這樣做拋棄異常數(shù)據(jù)。

為什么要發(fā)送basic.reject消息而不是ACK?RabbitMQ后面的版本可能會(huì)引入”dead letter”隊(duì)列,如果想利用dead letter做點(diǎn)文章就使用basic.reject并設(shè)置requeue為false。

消息持久化

RabbitMQ支持消息的持久化,也就是數(shù)據(jù)寫在磁盤上,為了數(shù)據(jù)安全考慮,大多數(shù)用戶都會(huì)選擇持久化。消息隊(duì)列持久化包括3個(gè)部分:

1.Exchange持久化,在聲明時(shí)指定durable => 1

2.Queue持久化,在聲明時(shí)指定durable => 1

3.消息持久化,在投遞時(shí)指定delivery_mode => 2(1是非持久化)

若Exchange和Queue都是持久化的,那么它們之間的Binding也是持久化的;而Exchange和Queue兩者之間有一個(gè)持久化,一個(gè)非持久化,就不允許建立綁定。

Consumer從durable queue中取回一條消息之后并發(fā)回了ack消息,RabbitMQ就會(huì)將其標(biāo)記,方便后續(xù)垃圾回收。如果一條持久化的消息沒有被consumer取走,RabbitMQ重啟之后會(huì)自動(dòng)重建exchange和queue(以及bingding關(guān)系),消息通過持久化日志重建再次進(jìn)入對(duì)應(yīng)的queues,exchanges。

RabbitMQ集群

由于RabbitMQ是用erlang開發(fā)的,RabbitMQ完全依賴erlang的Cluster,因?yàn)閑rlang天生就是一門分布式語言,集群非常方便,但其本身并不支持負(fù)載均衡。Erlang的集群中各節(jié)點(diǎn)是經(jīng)由過程一個(gè)magic cookie來實(shí)現(xiàn)的,這個(gè)cookie存放在 $home/.erlang.cookie中(像我的root用戶安裝的就是放在我的root/.erlang.cookie中),文件是400的權(quán)限。所以必須保證各節(jié)點(diǎn)cookie內(nèi)容一致,不然節(jié)點(diǎn)之間就無法通信。

集群方式

Rabbitmq集群大概分為二種方式:

1.普通模式:默認(rèn)的集群模式。

對(duì)于Queue來說,消息實(shí)體只存在于其中一個(gè)節(jié)點(diǎn),A、B兩個(gè)節(jié)點(diǎn)僅有相同的元數(shù)據(jù),即隊(duì)列結(jié)構(gòu),但隊(duì)列的元數(shù)據(jù)僅保存有一份,即創(chuàng)建該隊(duì)列的rabbitmq節(jié)點(diǎn)(A節(jié)點(diǎn)),當(dāng)A節(jié)點(diǎn)宕機(jī),你可以去其B節(jié)點(diǎn)查看,./rabbitmqctl list_queues 發(fā)現(xiàn)該隊(duì)列已經(jīng)丟失,但聲明的exchange還存在。

當(dāng)消息進(jìn)入A節(jié)點(diǎn)的Queue中后,consumer從B節(jié)點(diǎn)拉取時(shí),RabbitMQ會(huì)臨時(shí)在A、B間進(jìn)行消息傳輸,把A中的消息實(shí)體取出并經(jīng)過B發(fā)送給consumer,所以consumer應(yīng)平均連接每一個(gè)節(jié)點(diǎn),從中取消息。

該模式存在一個(gè)問題就是當(dāng)A節(jié)點(diǎn)故障后,B節(jié)點(diǎn)無法取到A節(jié)點(diǎn)中還未消費(fèi)的消息實(shí)體。如果做了隊(duì)列持久化或消息持久化,那么得等A節(jié)點(diǎn)恢復(fù),然后才可被消費(fèi),并且在A節(jié)點(diǎn)恢復(fù)之前其它節(jié)點(diǎn)不能再創(chuàng)建A節(jié)點(diǎn)已經(jīng)創(chuàng)建過的持久隊(duì)列;如果沒有持久化的話,消息就會(huì)失丟。

這種模式更適合非持久化隊(duì)列,只有該隊(duì)列是非持久的,客戶端才能重新連接到集群里的其他節(jié)點(diǎn),并重新創(chuàng)建隊(duì)列。假如該隊(duì)列是持久化的,那么唯一辦法是將故障節(jié)點(diǎn)恢復(fù)起來。

2.鏡像模式:把需要的隊(duì)列做成鏡像隊(duì)列,存在于多個(gè)節(jié)點(diǎn)。

該模式解決了普通模式的問題,其實(shí)質(zhì)不同之處在于,消息實(shí)體會(huì)主動(dòng)在鏡像節(jié)點(diǎn)間同步,而不是在consumer取數(shù)據(jù)時(shí)臨時(shí)拉取。

該模式帶來的副作用也很明顯,除了降低系統(tǒng)性能外,如果鏡像隊(duì)列數(shù)量過多,加之大量的消息進(jìn)入,集群內(nèi)部的網(wǎng)絡(luò)帶寬將會(huì)被這種同步通訊大大消耗掉。

所以在對(duì)可靠性要求較高的場(chǎng)合中適用,一個(gè)隊(duì)列想做成鏡像隊(duì)列,需要先設(shè)置policy,然后客戶端創(chuàng)建隊(duì)列的時(shí)候,rabbitmq集群根據(jù)“隊(duì)列名稱”自動(dòng)設(shè)置是普通集群模式或鏡像隊(duì)列。具體如下:

隊(duì)列通過策略來使能鏡像。策略能在任何時(shí)刻改變,rabbitmq隊(duì)列也近可能的將隊(duì)列隨著策略變化而變化;非鏡像隊(duì)列和鏡像隊(duì)列之間是有區(qū)別的,前者缺乏額外的鏡像基礎(chǔ)設(shè)施,沒有任何slave,因此會(huì)運(yùn)行得更快。

為了使隊(duì)列稱為鏡像隊(duì)列,你將會(huì)創(chuàng)建一個(gè)策略來匹配隊(duì)列,設(shè)置策略有兩個(gè)鍵“ha-mode和 ha-params(可選)”。ha-params根據(jù)ha-mode設(shè)置不同的值,下面表格說明這些key的選項(xiàng)。

為什么RabbitMQ不將隊(duì)列復(fù)制到集群里每個(gè)節(jié)點(diǎn)呢?這與它的集群的設(shè)計(jì)本意相沖突,集群的設(shè)計(jì)目的就是增加更多節(jié)點(diǎn)時(shí),能線性的增加性能(CPU、內(nèi)存)和容量(內(nèi)存、磁盤)。理由如下:

Storage Space: If every cluster node had a full copy of every queue, adding nodes wouldn’t give you more storage capacity. For example, if one node could store 1GB of messages, adding two more nodes would simply give you two more copies of the same 1GB of messages.(存儲(chǔ)空間:如果每個(gè)集群節(jié)點(diǎn)每個(gè)隊(duì)列的一個(gè)完整副本,增加節(jié)點(diǎn)需要更多的存儲(chǔ)容量。例如,如果一個(gè)節(jié)點(diǎn)可以存儲(chǔ)1 gb的消息,添加兩個(gè)節(jié)點(diǎn)需要兩份相同的1gb的消息)

Performance: Publishing messages would require replicating those messages to every cluster node. For durable messages that would require triggering disk activity on all nodes for every message. Your network and disk load would increase every time you added a node, keeping the performance of the cluster the same (or possibly worse).(性能:發(fā)布消息需要將這些信息復(fù)制到每個(gè)集群節(jié)點(diǎn)。對(duì)持久消息,要求為每條消息觸發(fā)磁盤活動(dòng)在所有節(jié)點(diǎn)上。每次添加一個(gè)節(jié)點(diǎn)都會(huì)帶來 網(wǎng)絡(luò)和磁盤的負(fù)載。)

當(dāng)然RabbitMQ新版本集群也支持隊(duì)列復(fù)制(有個(gè)選項(xiàng)可以配置)。比如在有五個(gè)節(jié)點(diǎn)的集群里,可以指定某個(gè)隊(duì)列的內(nèi)容在2個(gè)節(jié)點(diǎn)上進(jìn)行存儲(chǔ),從而在性能與高可用性之間取得一個(gè)平衡(應(yīng)該就是指鏡像模式)。

集群節(jié)點(diǎn)

RabbitMQ的集群節(jié)點(diǎn)包括內(nèi)存節(jié)點(diǎn)、磁盤節(jié)點(diǎn)。顧名思義內(nèi)存節(jié)點(diǎn)就是將所有數(shù)據(jù)放在內(nèi)存,磁盤節(jié)點(diǎn)將數(shù)據(jù)放在磁盤。不過,如果在投遞消息時(shí),打開了消息的持久化,那么即使是內(nèi)存節(jié)點(diǎn),數(shù)據(jù)還是安全的放在磁盤。

一個(gè)rabbitmq集 群中可以共享 user,vhost,queue,exchange等,所有的數(shù)據(jù)和狀態(tài)都是必須在所有節(jié)點(diǎn)上復(fù)制的,一個(gè)例外是,那些當(dāng)前只屬于創(chuàng)建它的節(jié)點(diǎn)的消息隊(duì)列,盡管它們可見且可被所有節(jié)點(diǎn)讀取。rabbitmq節(jié)點(diǎn)可以動(dòng)態(tài)的加入到集群中,一個(gè)節(jié)點(diǎn)它可以加入到集群中,也可以從集群環(huán)集群會(huì)進(jìn)行一個(gè)基本的負(fù)載均衡。

集群中有兩種節(jié)點(diǎn):

1.內(nèi)存節(jié)點(diǎn):只保存狀態(tài)到內(nèi)存(一個(gè)例外的情況是:持久的queue的持久內(nèi)容將被保存到disk)

2.磁盤節(jié)點(diǎn):保存狀態(tài)到內(nèi)存和磁盤。

內(nèi)存節(jié)點(diǎn)雖然不寫入磁盤,但是它執(zhí)行比磁盤節(jié)點(diǎn)要好。集群中,只需要一個(gè)磁盤節(jié)點(diǎn)來保存狀態(tài) 就足夠了如果集群中只有內(nèi)存節(jié)點(diǎn),那么不能停止它們,否則所有的狀態(tài),消息等都會(huì)丟失。

總結(jié)

以上是生活随笔為你收集整理的RabbitMq--1的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。