1、RabbitMQ中的broker是指什么?cluster又是指什么?
broker是指一個(gè)或多個(gè)erlang node的邏輯分組,且node上運(yùn)行著 RabbitMQ應(yīng)用程序。cluster是在broker的基礎(chǔ)之上,增加了 node之間 共享元數(shù)據(jù)的約束。
2、什么是元數(shù)據(jù)?元數(shù)據(jù)分為哪些類(lèi)型?包括哪些內(nèi)容?與cluster相關(guān)的元數(shù)據(jù)有哪些?元數(shù)據(jù)是如何保存的?元數(shù)據(jù)在cluster中是如何分布的?
在非cluster模式下,元數(shù)據(jù)主要分為Queue元數(shù)據(jù)(queue名字和屬性 等)、Exchange元數(shù)據(jù)(exchange名字、類(lèi)型和屬性等)、Binding元數(shù)據(jù) (存放路由關(guān)系的查找表)、Vhost元數(shù)據(jù)(vhost范圍內(nèi)針對(duì)前三者的名字空 間約束和安全屬性設(shè)置)。
在cluster模式下,還包括cluster中node位置信息和node關(guān)系信息。元數(shù)據(jù)按照erlang node的類(lèi)型確定是僅保存于RAM中,還是同時(shí)保存在RAM和disk上。元數(shù)據(jù)在cluster中是全node 分布的。
3、RAM node 和 disk node 的區(qū)別?
RAM node 僅將 fabric(即 queue、exchange 和 binding等 RabbitMQ基礎(chǔ)構(gòu) 件)相關(guān)元數(shù)據(jù)保存到內(nèi)存中,但disk node會(huì)在內(nèi)存和磁盤(pán)中均進(jìn)行存 儲(chǔ)。RAM node上唯一會(huì)存儲(chǔ)到磁盤(pán)上的元數(shù)據(jù)是cluster中使用的disk node的地址。要求在RabbitMQ cluster中至少存在一個(gè)disk node。
4、RabbitMQ上的一個(gè)queue中存放的message是否有數(shù)量限制?
可以認(rèn)為是無(wú)限制,因?yàn)橄拗迫Q于機(jī)器的內(nèi)存,但是消息過(guò)多會(huì)導(dǎo)致處 理效率的下降。
5、vhost是什么?起什么作用?
vhost可以理解為虛擬broker ,即mini-RabbitMQ server。其內(nèi)部均含有 獨(dú)立的queue、exchange和binding等,但最最重要的是,其擁有獨(dú)立的 權(quán)限系統(tǒng),可以做到vhost范圍的用戶(hù)控制。當(dāng)然,從RabbitMQ的全局 角度,vhost可以作為不同權(quán)限隔離的手段(一個(gè)典型的例子就是不同的應(yīng) 用可以跑在不同的vhost中)。
6、在單node系統(tǒng)和多node構(gòu)成的cluster系統(tǒng)中聲明queue、exchange,以及進(jìn)行binding會(huì)有什么不同?
當(dāng)你在單node上聲明queue時(shí),只要該node上相關(guān)元數(shù)據(jù)進(jìn)行了變 更,你就會(huì)得到Queue.Declare-ok回應(yīng);而在cluster上聲明queue,則要 求cluster上的全部node都要進(jìn)行元數(shù)據(jù)成功更新,才會(huì)得到 Queue.Declare-ok回應(yīng)。另外,若node類(lèi)型為RAM node則變更的數(shù)據(jù) 僅保存在內(nèi)存中,若類(lèi)型為disk node則還要變更保存在磁盤(pán)上的數(shù)據(jù)。
7、客戶(hù)端連接到cluster中的任意node上是否都能正常工作?
是的??蛻?hù)端感覺(jué)不到有何不同。
8、若cluster中擁有某個(gè)queue的owner node失效了,且該queue 被聲明具有durable屬性,是否能夠成功從其他node上重新聲明該 queue ?
不能,在這種情況下,將得到404 NOT_FOUND錯(cuò)誤。只能等queue所 屬的node恢復(fù)后才能使用該queue。但若該queue本身不具有durable 屬性,則可在其他node上重新聲明。
9、cluster中node的失效會(huì)對(duì)consumer產(chǎn)生什么影響?若是在 cluster 中創(chuàng)建了 mirrored queue,這時(shí) node 失效會(huì)對(duì) consumer 產(chǎn)生什么影響?
若是consumer所連接的那個(gè)node失效(無(wú)論該node是否為consumer 所訂閱queue的owner node),則consumer會(huì)在發(fā)現(xiàn)TCP連接斷開(kāi)時(shí), 按標(biāo)準(zhǔn)行為執(zhí)行重連邏輯,并根據(jù)“Assume Nothing”原則重建相應(yīng)的 fabric 即可。若是失效的 node 為 consumer 訂閱 queue 的 o wner node, 則 consumer 只能通過(guò) Consumer Cancellation Notification 機(jī)制來(lái)檢測(cè)與 該queue訂閱關(guān)系的終止,否則會(huì)出現(xiàn)傻等卻沒(méi)有任何消息來(lái)到的問(wèn) 題。
10、能夠在地理上分開(kāi)的不同數(shù)據(jù)中心使用RabbitMQ cluster么?
不能。
第一,你無(wú)法控制所創(chuàng)建的queue實(shí)際分布在cluster里的哪個(gè)node上 (一般使用HAProxy + cluster模型時(shí)都是這樣),這可能會(huì)導(dǎo)致各種跨地域 訪問(wèn)時(shí)的常見(jiàn)問(wèn)題;
第二,Erlang的OTP通信框架對(duì)延遲的容忍度有限,這可能會(huì)觸發(fā)各種 超時(shí),導(dǎo)致業(yè)務(wù)疲于處理;
第三,在廣域網(wǎng)上的連接失效問(wèn)題將導(dǎo)致經(jīng)典的“腦裂"問(wèn)題,而 RabbitMQ目前無(wú)法處理(該問(wèn)題主要是說(shuō)Mnesia)。
11、為什么heavy RPC的使用場(chǎng)景下不建議采用disk node
heavy RPC是指在業(yè)務(wù)邏輯中高頻調(diào)用RabbitMQ提供的RPC機(jī)制,導(dǎo) 致不斷創(chuàng)建、銷(xiāo)毀reply queue,進(jìn)而造成disk node的性能問(wèn)題(因?yàn)闀?huì) 針對(duì)元數(shù)據(jù)不斷寫(xiě)盤(pán))。所以在使用RPC機(jī)制時(shí)需要考慮自身的業(yè)務(wù)場(chǎng)景。
12、向不存在的exchange發(fā)publish消息會(huì)發(fā)生什么?向不存在的 queue執(zhí)行c onsume動(dòng)作會(huì)發(fā)生什么?
都會(huì)收到ChanneLClose信令告之不存在(內(nèi)含原因404 NOT_FOUND)。
13、routing_key和binding_key的最大長(zhǎng)度是多少?
255字節(jié)。
14、RabbitMQ允許發(fā)送的message最大可達(dá)多大?
根據(jù)AMQP協(xié)議規(guī)定,消息體的大小由64-bit的值來(lái)指定,所以你就可 以知道到底能發(fā)多大的數(shù)據(jù)了。
15、什么情況下producer不主動(dòng)創(chuàng)建queue是安全的?
message是允許丟失的;
實(shí)現(xiàn)了針對(duì)未處理消息的republish功能(例如采用Publisher Confirm機(jī) 制)。
16、"dead letter" queue 的用途?
當(dāng)消息被RabbitMQ server投遞到consumer后,但consumer卻通過(guò) Basic.Reject進(jìn)行了拒絕時(shí)(同時(shí)設(shè)置requeue=false),那么該消息會(huì)被放 入“dead letter"queue 中。該 queue 可用于排查 message 被 reject 或 undeliver 的原因。
17、什么說(shuō)保證message被可靠持久化的條件是queue和exchange 具有durable屬性,同時(shí)message具有persistent屬性才行?
binding關(guān)系可以表示為exchange - binding - queue。從文檔中我們知 道,若要求投遞的message能夠不丟失,要求message本身設(shè)置 persistent屬性,要求exchange和queue都設(shè)置durable屬性。
其實(shí)這問(wèn) 題可以這么想,若exchange或queue未設(shè)置durable屬性,則在其 crash之后就會(huì)無(wú)法恢復(fù),那么即使message設(shè)置了 persistent屬性,仍 然存在message雖然能恢復(fù)但卻無(wú)處容身的問(wèn)題;同理,若message本身 未設(shè)置persistent屬性,則message的持久化更無(wú)從談起。
18、什么情況下會(huì)出現(xiàn)blackholed問(wèn)題?
blackholed問(wèn)題是指,向exchange投遞了 message,而由于各種原因?qū)?致該message丟失,但發(fā)送者卻不知道??蓪?dǎo)致blackholed的情況:
向未綁定 queue 的 exchange 發(fā)送 message;
exchange 以 binding_key key_A 綁定了 queue queue_A,但向該 exchange 發(fā)送 message 使用的 routing_key 去卩是 key_B。
19、如何防止出現(xiàn)blackholed問(wèn)題?
沒(méi)有特別好的辦法,只能在具體實(shí)踐中通過(guò)各種方式保證相關(guān)fabric的存 在。另外,如果在執(zhí)行Basic.Publish時(shí)設(shè)置mandatory=true,則在遇到 可能出現(xiàn)blackholed情況時(shí),服務(wù)器會(huì)通過(guò)返回Basic.Return告之當(dāng)前 message無(wú)法被正確投遞(內(nèi)含原因312 NO_ROUTE)。
20、Consumer Cancellation Notification 機(jī)制用于什么場(chǎng)景?
用于保證當(dāng)鏡像queue中master掛掉時(shí),連接到slave上的consumer可 以收到自身consume被取消的通知,進(jìn)而可以重新執(zhí)行consume動(dòng)作從 新選出的master出獲得消息。
若不采用該機(jī)制,連接到slave上的 consumer將不會(huì)感知master掛掉這個(gè)事情,導(dǎo)致后續(xù)無(wú)法再收到新 master廣播出來(lái)的message。
另外,因?yàn)樵阽R像queue模式下,存在將 message進(jìn)行requeue的可能,所以實(shí)現(xiàn)consumer的邏輯時(shí)需要能夠正 確處理出現(xiàn)重復(fù)message的情況。
21、Basic.Reject的用法是什么?
該信令可用于consumer對(duì)收到的message進(jìn)行reject。若在該信令中設(shè) 置requeue=true,則當(dāng)RabbitMQ server收到該拒絕信令后,會(huì)將該 message重新發(fā)送到下一個(gè)處于consume狀態(tài)的consumer處(理論上仍 可能將該消息發(fā)送給當(dāng)前consumer)。若設(shè)置requeue=false,則 RabbitMQ server在收到拒絕信令后,將直接將該message從queue中移 除。
另外一種移除queue中message的小技巧是,consumer回復(fù)Basic.Ack 但不對(duì)獲取到的message做任何處理。
而B(niǎo)asic.Nack是對(duì)Basic.Reject的擴(kuò)展,以支持一次拒絕多條message 的能力。
22、為什么不應(yīng)該對(duì)所有的message都使用持久化機(jī)制?
首先,必然導(dǎo)致性能的下降,因?yàn)閷?xiě)磁盤(pán)比寫(xiě)RAM慢的多,message的 吞吐量可能有10倍的差距。其次,message的持久化機(jī)制用在 RabbitMQ的內(nèi)置cluster方案時(shí)會(huì)出現(xiàn)“坑爹”問(wèn)題。矛盾點(diǎn)在于,若 message設(shè)置了 persistent屬性,但 queue未設(shè)置 durable屬性,那么當(dāng) 該queue的owner node出現(xiàn)異常后,在未重建該queue前,發(fā)往該 queue 的 message 將被 blackholed ;若 message 設(shè)置了 persistent 屬性, 同時(shí)queue也設(shè)置了 durable屬性,那么當(dāng)queue的owner node異常且 無(wú)法重啟的情況下,則該queue無(wú)法在其他node上重建,只能等待其 owner node重啟后,才能恢復(fù)該queue的使用,而在這段時(shí)間內(nèi)發(fā)送給 該queue的message將被blackholed。
所以,是否要對(duì)message進(jìn)行持久化,需要綜合考慮性能需要,以及可能遇到的問(wèn)題。若想達(dá)到 100,000條/秒以上的消息吞吐量(單RabbitMQ服務(wù)器),則要么使用其他 的方式來(lái)確保message的可靠delivery,要么使用非??焖俚拇鎯?chǔ)系統(tǒng)以 支持全持久化(例如使用SSD)。另外一種處理原則是:僅對(duì)關(guān)鍵消息作持久 化處理(根據(jù)業(yè)務(wù)重要程度),且應(yīng)該保證關(guān)鍵消息的量不會(huì)導(dǎo)致性能瓶 頸。
23、RabbitMQ 中的 cluster、mirrored queue,以及 warrens 機(jī)制分 別用于解決什么問(wèn)題?存在哪些問(wèn)題?
cluster是為了解決當(dāng)cluster中的任意node失效后,producer和 consumer均可以通過(guò)其他node繼續(xù)工作,即提高了可用性;另外可以通 過(guò)增加node數(shù)量增加cluster的消息吞吐量的目的。
cluster本身不負(fù)責(zé) message的可靠性問(wèn)題(該問(wèn)題由producer通過(guò)各種機(jī)制自行解 決);cluster無(wú)法解決跨數(shù)據(jù)中心的問(wèn)題(即腦裂問(wèn)題)。
另外,在cluster前使用HAProxy可以解決node的選擇問(wèn)題,即業(yè)務(wù)無(wú) 需知道cluster中多個(gè)node的ip地址??梢岳肏AProxy進(jìn)行失效node 的探測(cè),可以作負(fù)載均衡。
Mirrored queue是為了解決使用cluster時(shí)所創(chuàng)建的queue的完整信息僅 存在于單一node上的問(wèn)題,從另一個(gè)角度增加可用性。若想正確使用該 功能,需要保證:
consumer 需要支持 Consumer Cancellation Notification 機(jī)制;
consumer必須能夠正確處理重復(fù)message。
Warrens是為了解決cluster中message可能被blackholed的問(wèn)題,即不 能接受 producer 不停 republish message 但 RabbitMQ server 無(wú)回應(yīng)的情況。Warrens有兩種構(gòu)成方式:
一種模型是兩臺(tái)獨(dú)立的RabbitMQ server + HAProxy,其中兩個(gè)server的 狀態(tài)分別為active和hot-standby。該模型的特點(diǎn)為:兩臺(tái)server之間無(wú)任 何數(shù)據(jù)共享和協(xié)議交互,兩臺(tái)server可以基于不同的RabbitMQ版本。
另一種模型為兩臺(tái)共享存儲(chǔ)的RabbitMQ server + keepalived,其中兩個(gè) server 的狀態(tài)分別為 active 和 cold-standby。
該模型的特點(diǎn)為:兩臺(tái)server基于共享存儲(chǔ)可以做到完全恢復(fù),要求必須 基于完全相同的RabbitMQ版本。
Warrens模型存在的問(wèn)題:
對(duì)于第一種模型,雖然理論上講不會(huì)丟失消息,但若在該模型上使用持久 化機(jī)制,就會(huì)出現(xiàn)這樣一種情況,即若作為active的server異常后,持久 化在該server上的消息將暫時(shí)無(wú)法被consume,因?yàn)榇藭r(shí)該queue將無(wú) 法在作為hot- standby的server上被重建,所以,只能等到異常的active server恢復(fù)后,才能從其上的queue中獲取相應(yīng)的message進(jìn)行處理。 而對(duì)于業(yè)務(wù)來(lái)說(shuō),需要具有:a .感知AMQP連接斷開(kāi)后重建各種fabric的能 力;b.感知active server恢復(fù)的能力;c.切換回active server的時(shí)機(jī)控制,以及切回后,針對(duì)message先后順序產(chǎn)生的變化進(jìn)行處理的能力。
對(duì)于第二種模型,因?yàn)槭腔诠蚕泶鎯?chǔ)的模式,所以導(dǎo)致active server異 常的條件,可能同樣會(huì)導(dǎo)致cold-standby server異常;另外,在該模型下, 要求active和cold-standby的server必須具有相同的node名和UID,否 則將產(chǎn)生訪問(wèn)權(quán)限問(wèn)題;最后,由于該模型是冷備方案,故無(wú)法保證cold standby server能在你要求的時(shí)限內(nèi)成功啟動(dòng)。