新聞中心
本次學(xué)習(xí)主要針對(duì)運(yùn)維人員,和對(duì)rabbitmq不熟悉的開(kāi)發(fā)人員。通過(guò)本次學(xué)習(xí)你將掌握rabbitmq 的基本原理、集群、基本運(yùn)維操作、常見(jiàn)故障處理。

堅(jiān)守“ 做人真誠(chéng) · 做事靠譜 · 口碑至上 · 高效敬業(yè) ”的價(jià)值觀,專(zhuān)業(yè)網(wǎng)站建設(shè)服務(wù)10余年為成都成都VR全景小微創(chuàng)業(yè)公司專(zhuān)業(yè)提供企業(yè)網(wǎng)站建設(shè)營(yíng)銷(xiāo)網(wǎng)站建設(shè)商城網(wǎng)站建設(shè)手機(jī)網(wǎng)站建設(shè)小程序網(wǎng)站建設(shè)網(wǎng)站改版,從內(nèi)容策劃、視覺(jué)設(shè)計(jì)、底層架構(gòu)、網(wǎng)頁(yè)布局、功能開(kāi)發(fā)迭代于一體的高端網(wǎng)站建設(shè)服務(wù)。
1、原理與概念
簡(jiǎn)介
AMQP,即Advanced Message Queuing Protocol,高級(jí)消息隊(duì)列協(xié)議,是應(yīng)用層協(xié)議的一個(gè)開(kāi)放標(biāo)準(zhǔn),為面向消息的中間件設(shè)計(jì)。消息中間件主要用于組件之間的解耦,消息的發(fā)送者無(wú)需知道消息使用者的存在,反之亦然。
AMQP的主要特征是面向消息、隊(duì)列、路由(包括點(diǎn)對(duì)點(diǎn)和發(fā)布/訂閱)、可靠性、安全。 RabbitMQ是一個(gè)開(kāi)源的AMQP實(shí)現(xiàn),服務(wù)器端用Erlang語(yǔ)言編寫(xiě),支持多種客戶(hù)端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系統(tǒng)中存儲(chǔ)轉(zhuǎn)發(fā)消息,在易用性、擴(kuò)展性、高可用性等方面表現(xiàn)不俗。
解決的問(wèn)題
RabbitMQ就是當(dāng)前主流的消息中間件之一。
- 兩個(gè)(多個(gè))系統(tǒng)間需要通過(guò)定時(shí)任務(wù)來(lái)同步某些數(shù)據(jù)
- 異構(gòu)系統(tǒng)的不同進(jìn)程間相互調(diào)用、通訊的問(wèn)題
Queue
Queue(隊(duì)列)是RabbitMQ的內(nèi)部對(duì)象,用于存儲(chǔ)消息,用下圖表示。
RabbitMQ中的消息都只能存儲(chǔ)在Queue中,生產(chǎn)者(下圖中的P)生產(chǎn)消息并最終投遞到Queue中,消費(fèi)者(下圖中的C)可以從Queue中獲取消息并消費(fèi)。
多個(gè)消費(fèi)者可以訂閱同一個(gè)Queue,這時(shí)Queue中的消息會(huì)被平均分?jǐn)偨o多個(gè)消費(fèi)者進(jìn)行處理,而不是每個(gè)消費(fèi)者都收到所有的消息并處理。
技術(shù)術(shù)語(yǔ)
- Broker:簡(jiǎn)單來(lái)說(shuō)就是消息隊(duì)列服務(wù)器實(shí)體。
- producer:消息生產(chǎn)者,就是投遞消息的程序。
- consumer:消息消費(fèi)者,就是接受消息的程序。
- vhost:虛擬主機(jī),一個(gè)broker里可以開(kāi)設(shè)多個(gè)vhost,用作權(quán)限分離,把不同的系統(tǒng)使用的rabbitmq區(qū)分開(kāi),共用一個(gè)消息隊(duì)列服務(wù)器,但看上去就像各自在用不用的rabbitmq服務(wù)器一樣。
- Connection:一個(gè)網(wǎng)絡(luò)連接,比如TCP/IP套接字連接。
- channel:消息通道,是建立在真實(shí)的TCP連接內(nèi)的虛擬連接(是我們與RabbitMQ打交道的最重要的一個(gè)接口)。僅僅創(chuàng)建了客戶(hù)端到Broker之間的連接后,客戶(hù)端還是不能發(fā)送消息的,需要為每一個(gè)Connection創(chuàng)建Channel,AMQP協(xié)議規(guī)定只有通過(guò)Channel才能執(zhí)行AMQP的命令。AMQP的命令都是通過(guò)信道發(fā)送出去的(我們大部分的業(yè)務(wù)操作是在Channel這個(gè)接口中完成的,包括定義Queue、定義Exchange、綁定Queue與Exchange、發(fā)布消息等。)。每條信道都會(huì)被指派一個(gè)唯一ID。在客戶(hù)端的每個(gè)連接里,可建立多個(gè)channel,每個(gè)channel代表一個(gè)會(huì)話任務(wù),理論上無(wú)限制,減少TCP創(chuàng)建和銷(xiāo)毀的開(kāi)銷(xiāo),實(shí)現(xiàn)共用TCP的效果。之所以需要Channel,是因?yàn)門(mén)CP連接的建立和釋放都是十分昂貴的,如果一個(gè)客戶(hù)端每一個(gè)線程都需要與Broker交互,如果每一個(gè)線程都建立一個(gè)TCP連接,暫且不考慮TCP連接是否浪費(fèi),就算操作系統(tǒng)也無(wú)法承受每秒建立如此多的TCP連接。 注1:一個(gè)生產(chǎn)者或一個(gè)消費(fèi)者與MQ服務(wù)器之間只有一條TCP連接 注2:RabbitMQ建議客戶(hù)端線程之間不要共用Channel,至少要保證共用Channel的線程發(fā)送消息必須是串行的,但是建議盡量共用Connection。
- Exchange:消息交換機(jī),生產(chǎn)者不是直接將消息投遞到Queue中的,實(shí)際上是生產(chǎn)者將消息發(fā)送到Exchange(交換器,下圖中的X),由Exchange將消息路由到一個(gè)或多個(gè)Queue中(或者丟棄)。
- Exchange Types RabbitMQ常用的Exchange Type有fanout、direct、topic、headers這四種(AMQP規(guī)范里還提到兩種Exchange Type,分別為system與自定義,這里不予以描述),之后會(huì)分別進(jìn)行介紹。
- Queue:消息隊(duì)列載體,每個(gè)消息都會(huì)被投入到一個(gè)或多個(gè)隊(duì)列。
- Binding:綁定,它的作用就是把exchange和queue按照路由規(guī)則綁定起來(lái),這樣RabbitMQ就知道如何正確地將消息路由到指定的Queue了。
- Routing Key:路由關(guān)鍵字,生產(chǎn)者在將消息發(fā)送給Exchange的時(shí)候,一般會(huì)指定一個(gè)routing key,來(lái)指定這個(gè)消息的路由規(guī)則,而這個(gè)routing key需要與Exchange Type及binding key聯(lián)合使用才能最終生效。
- 在Exchange Type與binding key固定的情況下(在正常使用時(shí)一般這些內(nèi)容都是固定配置好的),我們的生產(chǎn)者就可以在發(fā)送消息給Exchange時(shí),通過(guò)指定routing key來(lái)決定消息流向哪里。
- Prefetch count 前面我們講到如果有多個(gè)消費(fèi)者同時(shí)訂閱同一個(gè)Queue中的消息,Queue中的消息會(huì)被平攤給多個(gè)消費(fèi)者。這時(shí)如果每個(gè)消息的處理時(shí)間不同,就有可能會(huì)導(dǎo)致某些消費(fèi)者一直在忙,而另外一些消費(fèi)者很快就處理完手頭工作并一直空閑的情況。我們可以通過(guò)設(shè)置prefetchCount來(lái)限制Queue每次發(fā)送給每個(gè)消費(fèi)者的消息數(shù),比如我們?cè)O(shè)置prefetchCount=1,則Queue每次給每個(gè)消費(fèi)者發(fā)送一條消息;消費(fèi)者處理完這條消息后Queue會(huì)再給該消費(fèi)者發(fā)送一條消息。
消息隊(duì)列的使用過(guò)程
在AMQP模型中,Exchange是接受生產(chǎn)者消息并將消息路由到消息隊(duì)列的關(guān)鍵組件。ExchangeType和Binding決定了消息的路由規(guī)則。所以生產(chǎn)者想要發(fā)送消息,首先必須要聲明一個(gè)Exchange和該Exchange對(duì)應(yīng)的Binding。
在Rabbit MQ中,聲明一個(gè)Exchange需要三個(gè)參數(shù):ExchangeName,ExchangeType和Durable。ExchangeName是該Exchange的名字,該屬性在創(chuàng)建Binding和生產(chǎn)者通過(guò)publish推送消息時(shí)需要指定。ExchangeType,指Exchange的類(lèi)型,在RabbitMQ中,有三種類(lèi)型的Exchange:direct ,fanout和topic,不同的Exchange會(huì)表現(xiàn)出不同路由行為。Durable是該Exchange的持久化屬性,這個(gè)會(huì)在消息持久化章節(jié)討論。
聲明一個(gè)Binding需要提供一個(gè)QueueName,ExchangeName和BindingKey。
下面是消息發(fā)送的過(guò)程:
- 建立連接Connection。由producer和consumer創(chuàng)建連接,連接到broker的物理節(jié)點(diǎn)上。
- 建立消息Channel。Channel是建立在Connection之上的,一個(gè)Connection可以建立多個(gè)Channel。producer連接Virtual Host 建立Channel,Consumer連接到相應(yīng)的queue上建立Channel。
- 發(fā)送消息。由Producer發(fā)送消息到Broker中的Exchange中。
- 路由轉(zhuǎn)發(fā)。生產(chǎn)者Producer在發(fā)送消息時(shí),都需要指定一個(gè)RoutingKey和Exchange,Exchange收到消息后可以看到消息中指定的RoutingKey,再根據(jù)當(dāng)前Exchange的ExchangeType,按一定的規(guī)則將消息轉(zhuǎn)發(fā)到相應(yīng)的queue中去。
- 消息接收。Consumer會(huì)監(jiān)聽(tīng)相應(yīng)的queue,一旦queue中有可以消費(fèi)的消息,queue就將消息發(fā)送給Consumer端。
- 消息確認(rèn)。當(dāng)Consumer完成某一條消息的處理之后,需要發(fā)送一條ACK消息給對(duì)應(yīng)的Queue。Queue收到ACK信息后,才會(huì)認(rèn)為消息處理成功,并將消息從Queue中移除;如果在對(duì)應(yīng)的Channel斷開(kāi)后,Queue沒(méi)有收到這條消息的ACK信息,該消息將被發(fā)送給另外的Channel。至此一個(gè)消息的發(fā)送接收流程走完了。消息的確認(rèn)機(jī)制提高了通信的可靠性。
exchange 與 Queue 的路由機(jī)制
exchange 將消息發(fā)送到哪一個(gè)queue是由exchange type 和bing 規(guī)則決定的,目前常用的有3種exchange,Direct exchange, Fanout exchange, Topic exchange 。Direct exchange 直接轉(zhuǎn)發(fā)路由,其實(shí)現(xiàn)原理是通過(guò)消息中的routkey,與queue 中的routkey 進(jìn)行比對(duì),若二者匹配,則將消息發(fā)送到這個(gè)消息隊(duì)列。通常使用這個(gè)。
以上圖的配置為例,我們以routingKey=”error”發(fā)送消息到Exchange,則消息會(huì)路由到Queue1(amqp.gen-S9b…,這是由RabbitMQ自動(dòng)生成的Queue名稱(chēng))和Queue2(amqp.gen-Agl…);如果我們以routingKey=”info”或routingKey=”warning”來(lái)發(fā)送消息,則消息只會(huì)路由到Queue2。如果我們以其他routingKey發(fā)送消息,則消息不會(huì)路由到這兩個(gè)Queue中。
Fanout exchange 復(fù)制分發(fā)路由,該路由不需要routkey,當(dāng)exchange收到消息后,將消息復(fù)制多份轉(zhuǎn)發(fā)給與自己綁定的消息隊(duì)列。
上圖中,生產(chǎn)者(P)發(fā)送到Exchange(X)的所有消息都會(huì)路由到圖中的兩個(gè)Queue,并最終被兩個(gè)消費(fèi)者(C1與C2)消費(fèi)。topic exchange 通配路由,是direct exchange的通配符模式,消息中的routkey可以寫(xiě)成通配的模式,exchange支持“#”和“*” 的通配。收到消息后,將消息轉(zhuǎn)發(fā)給所有符合匹配表達(dá)式的queue。
以上圖中的配置為例,routingKey=”quick.orange.rabbit”的消息會(huì)同時(shí)路由到Q1與Q2,routingKey=”lazy.orange.fox”的消息會(huì)路由到Q1,routingKey=”lazy.brown.fox”的消息會(huì)路由到Q2,routingKey=”lazy.pink.rabbit”的消息會(huì)路由到Q2(只會(huì)投遞給Q2一次,雖然這個(gè)routingKey與Q2的兩個(gè)bindingKey都匹配);routingKey=”quick.brown.fox”、routingKey=”orange”、routingKey=”quick.orange.male.rabbit”的消息將會(huì)被丟棄,因?yàn)樗鼈儧](méi)有匹配任何bindingKey。
需要注意的一點(diǎn)只有queue具有 保持消息的功能,exchange不能保存消息。
headers headers類(lèi)型的Exchange不依賴(lài)于routing key與binding key的匹配規(guī)則來(lái)路由消息,而是根據(jù)發(fā)送的消息內(nèi)容中的headers屬性進(jìn)行匹配。 在綁定Queue與Exchange時(shí)指定一組鍵值對(duì);當(dāng)消息發(fā)送到Exchange時(shí),RabbitMQ會(huì)取到該消息的headers(也是一個(gè)鍵值對(duì)的形式),對(duì)比其中的鍵值對(duì)是否完全匹配Queue與Exchange綁定時(shí)指定的鍵值對(duì);如果完全匹配則消息會(huì)路由到該Queue,否則不會(huì)路由到該Queue。 該類(lèi)型的Exchange沒(méi)有用到過(guò)(不過(guò)也應(yīng)該很有用武之地),所以不做介紹。
durability 持久化與非持久化隊(duì)列
如何識(shí)別? 如上圖,在Features字段里有一個(gè)D,就是持久化隊(duì)列,英文durable(持久的)。
持久化隊(duì)列和非持久化隊(duì)列的區(qū)別是什么? 持久化隊(duì)列會(huì)被保存在磁盤(pán)中,固定并持久的存儲(chǔ),當(dāng)Rabbit服務(wù)重啟后,該隊(duì)列會(huì)保持原來(lái)的狀態(tài)在RabbitMQ中被管理,而非持久化隊(duì)列不會(huì)被保存在磁盤(pán)中,Rabbit服務(wù)重啟后隊(duì)列就會(huì)消失。
如何選擇? 如果需要隊(duì)列的完整性,數(shù)據(jù)在隊(duì)列中的保存是必須不允許丟失的,那么可以使用持久化。而當(dāng)需要獲取的信息是實(shí)時(shí)的,或者是隨機(jī)的信息,不需要信息的精確性或完整性,但是追求獲取性能,可以選擇非持久化隊(duì)列。
2、分布式集群架構(gòu)和高可用性
設(shè)計(jì)集群的目的:
- 允許消費(fèi)者和生產(chǎn)者在RabbitMQ節(jié)點(diǎn)崩潰的情況下繼續(xù)運(yùn)行
- 通過(guò)增加更多的節(jié)點(diǎn)來(lái)擴(kuò)展消息通信的吞吐量
集群配置方式:
RabbitMQ可以通過(guò)三種方法來(lái)部署分布式集群系統(tǒng),分別是:cluster,federation,shovel
- cluster:
不支持跨網(wǎng)段,用于同一個(gè)網(wǎng)段內(nèi)的局域網(wǎng)
可以隨意的動(dòng)態(tài)增加或者減少
節(jié)點(diǎn)之間需要運(yùn)行相同版本的RabbitMQ和Erlang。
- federation:應(yīng)用于廣域網(wǎng),允許單臺(tái)服務(wù)器上的交換機(jī)或隊(duì)列接收發(fā)布到另一臺(tái)服務(wù)器上交換機(jī)或隊(duì)列的消息,可以是單獨(dú)機(jī)器或集群。federation隊(duì)列類(lèi)似于單向點(diǎn)對(duì)點(diǎn)連接,消息會(huì)在聯(lián)盟隊(duì)列之間轉(zhuǎn)發(fā)任意次,直到被消費(fèi)者接受。通常使用federation來(lái)連接internet上的中間服務(wù)器,用作訂閱分發(fā)消息或工作隊(duì)列。
- shovel:連接方式與federation的連接方式類(lèi)似,但它工作在更低層次??梢詰?yīng)用于廣域網(wǎng)。
RabbitMQ cluster 集群同步原理
上面圖中采用三個(gè)節(jié)點(diǎn)組成了一個(gè)RabbitMQ的集群,Exchange A的元數(shù)據(jù)信息在所有節(jié)點(diǎn)上是一致的,而Queue(存放消息的隊(duì)列)的完整數(shù)據(jù)則只會(huì)存在于它所創(chuàng)建的那個(gè)節(jié)點(diǎn)上。,其他節(jié)點(diǎn)只知道這個(gè)queue的metadata信息和一個(gè)指向queue的owner node的指針。RabbitMQ集群元數(shù)據(jù)的同步。
RabbitMQ集群會(huì)始終同步四種類(lèi)型的內(nèi)部元數(shù)據(jù)(類(lèi)似索引):
- 隊(duì)列元數(shù)據(jù):隊(duì)列名稱(chēng)和它的屬性;
- 交換器元數(shù)據(jù):交換器名稱(chēng)、類(lèi)型和屬性;
- 綁定元數(shù)據(jù):一張簡(jiǎn)單的表格展示了如何將消息路由到隊(duì)列;
- vhost元數(shù)據(jù):為vhost內(nèi)的隊(duì)列、交換器和綁定提供命名空間和安全屬性; 因此,當(dāng)用戶(hù)訪問(wèn)其中任何一個(gè)RabbitMQ節(jié)點(diǎn)時(shí),通過(guò)rabbitmqctl查詢(xún)到的queue/user/exchange/vhost等信息都是相同的。
為何RabbitMQ集群僅采用元數(shù)據(jù)同步的方式
一,存儲(chǔ)空間,如果每個(gè)集群節(jié)點(diǎn)都擁有所有Queue的完全數(shù)據(jù)拷貝,那么每個(gè)節(jié)點(diǎn)的存儲(chǔ)空間會(huì)非常大,集群的消息積壓能力會(huì)非常弱(無(wú)法通過(guò)集群節(jié)點(diǎn)的擴(kuò)容提高消息積壓能力); 二,性能,消息的發(fā)布者需要將消息復(fù)制到每一個(gè)集群節(jié)點(diǎn),對(duì)于持久化消息,網(wǎng)絡(luò)和磁盤(pán)同步復(fù)制的開(kāi)銷(xiāo)都會(huì)明顯增加。
RabbitMQ cluster 集群的兩種模式
- 普通模式:默認(rèn)的集群模式。
- 鏡像模式:把需要的隊(duì)列做成鏡像隊(duì)列,存在于多個(gè)節(jié)點(diǎn),屬于RabbitMQ的HA方案。
普通模式:當(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)過(guò)B發(fā)送給consumer,所以consumer應(yīng)平均連接每一個(gè)節(jié)點(diǎn),從中取消息。該模式存在一個(gè)問(wèn)題就是當(dāng)A節(jié)點(diǎn)故障后,B節(jié)點(diǎn)無(wú)法取到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)建過(guò)的持久隊(duì)列;如果沒(méi)有持久化的話,消息就會(huì)失丟。這種模式更適合非持久化隊(duì)列,只有該隊(duì)列是非持久的,客戶(hù)端才能重新連接到集群里的其他節(jié)點(diǎn),并重新創(chuàng)建隊(duì)列。假如該隊(duì)列是持久化的,那么唯一辦法是將故障節(jié)點(diǎn)恢復(fù)起來(lái)。為什么RabbitMQ不將隊(duì)列復(fù)制到集群里每個(gè)節(jié)點(diǎn)呢?這與它的集群的設(shè)計(jì)本意相沖突,集群的設(shè)計(jì)目的就是增加更多節(jié)點(diǎn)時(shí),能線性的增加性能(CPU、內(nèi)存)和容量(內(nèi)存、磁盤(pán))。當(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)該就是指鏡像模式)。
鏡像模式:其實(shí)質(zhì)和普通模式不同之處在于,消息實(shí)體會(huì)主動(dòng)在鏡像節(jié)點(diǎn)間同步,而不是在consumer取數(shù)據(jù)時(shí)臨時(shí)拉取。該模式帶來(lái)的副作用也很明顯,除了降低系統(tǒng)性能外,如果鏡像隊(duì)列數(shù)量過(guò)多,加之大量的消息進(jìn)入,集群內(nèi)部的網(wǎng)絡(luò)帶寬將會(huì)被這種同步通訊大大消耗掉。所以在對(duì)可靠性要求較高的場(chǎng)合中適用。
節(jié)點(diǎn)類(lèi)型
RAM node:內(nèi)存節(jié)點(diǎn)將所有的隊(duì)列、交換機(jī)、綁定、用戶(hù)、權(quán)限和vhost的元數(shù)據(jù)定義存儲(chǔ)在內(nèi)存中,好處是可以使得像交換機(jī)和隊(duì)列聲明等操作更加的快速。
Disk node:將元數(shù)據(jù)存儲(chǔ)在磁盤(pán)中,單節(jié)點(diǎn)系統(tǒng)只允許磁盤(pán)類(lèi)型的節(jié)點(diǎn),防止重啟RabbitMQ的時(shí)候,丟失系統(tǒng)的配置信息。
如果是內(nèi)存結(jié)點(diǎn)這里就顯示為RAM注意:
- RabbitMQ要求在集群中至少有一個(gè)磁盤(pán)節(jié)點(diǎn),所有其他節(jié)點(diǎn)可以是內(nèi)存節(jié)點(diǎn),當(dāng)節(jié)點(diǎn)加入或者離開(kāi)集群時(shí),必須要將該變更通知到至少一個(gè)磁盤(pán)節(jié)點(diǎn)。
- 如果集群中唯一的一個(gè)磁盤(pán)節(jié)點(diǎn)崩潰的話,集群仍然可以保持運(yùn)行,但是無(wú)法進(jìn)行其他操作(包括創(chuàng)建隊(duì)列、交換器、綁定,添加用戶(hù)、更改權(quán)限、添加和刪除集群結(jié)點(diǎn)),直到節(jié)點(diǎn)恢復(fù)。
- 解決方案:設(shè)置兩個(gè)磁盤(pán)節(jié)點(diǎn),至少有一個(gè)是可用的,可以保存元數(shù)據(jù)的更改。
Erlang Cookie
Erlang Cookie是保證不同節(jié)點(diǎn)可以相互通信的密鑰,要保證集群中的不同節(jié)點(diǎn)相互通信必須共享相同的Erlang Cookie。具體的目錄存放在/var/lib/rabbitmq/.erlang.cookie。
3、基本運(yùn)維操作
rabbitmq集群必要條件
綁定實(shí)體ip,即ifconfig所能查詢(xún)到的綁定到網(wǎng)卡上的ip,以下是綁定方法
- #編輯配置路徑 /etc/rabbitmq/rabbitmq-env.conf
- NODE_IP_ADDRESS=172.16.136.133
- 復(fù)制代碼
配置域名映射到實(shí)體ip
- #配置文件1所在路徑 /etc/rabbitmq/rabbitmq.config (如果是集群,每臺(tái)機(jī)器都需要修改這個(gè)綁定本機(jī)實(shí)體ip)
- #其中rabbit@master是創(chuàng)建集群時(shí)所配置的參數(shù),@后面的參數(shù)為主機(jī)名,示例中為master
- [
- {rabbit, [
- {cluster_nodes, {['rabbit@master'], disc}},
- {cluster_partition_handling, ignore},
- {default_user, <<"guest">>},
- {default_pass, <<"guest">>},
- {tcp_listen_options, [binary,
- {packet, raw},
- {reuseaddr, true},
- {backlog, 128},
- {nodelay, true},
- {exit_on_close, false},
- {keepalive, true}]}
- ]},
- {kernel, [
- {inet_dist_listen_max, 44001},
- {inet_dist_listen_min, 44001}
- ]}
- ].
- 復(fù)制代碼
- #配置文件2 所在路徑 /etc/hosts (如果是集群,每臺(tái)機(jī)器都需要修改這個(gè)綁定本機(jī)實(shí)體ip,而且hosts文件的映射不得重復(fù),如果重復(fù)linux系統(tǒng)為以最下面一條記錄為準(zhǔn))
- 172.16.136.133 master
- 172.16.136.134 venus
- 172.16.136.135 venus2
啟動(dòng)停止
停止
- #機(jī)器A
- service rabbitmq-server stop
- epmd -kill
- #機(jī)器B
- service rabbitmq-server stop
- epmd -kill
- #機(jī)器C
- service rabbitmq-server stop
- epmd -kill
啟動(dòng)
方式1
- #機(jī)器A
- service rabbitmq-server start
- #機(jī)器B
- service rabbitmq-server start
- #機(jī)器C
- service rabbitmq-server start
方式2
- rabbitmq-server -detached
集群重啟順序
集群重啟的順序是固定的,并且是相反的。 如下所述:
啟動(dòng)順序:磁盤(pán)節(jié)點(diǎn) => 內(nèi)存節(jié)點(diǎn) 關(guān)閉順序:內(nèi)存節(jié)點(diǎn) => 磁盤(pán)節(jié)點(diǎn) 最后關(guān)閉必須是磁盤(pán)節(jié)點(diǎn),不然可能回造成集群?jiǎn)?dòng)失敗、數(shù)據(jù)丟失等異常情況。
重建集群
注1:此處的mq集群重建是比較快速和有效的方法,面向的是初次安裝或者可以接受mq中所存有的數(shù)據(jù)丟失的情況下,必須先有mq的.json后綴的配置文件或者有把握寫(xiě)入集群中exchange、queue等配置。
按順序停止所有機(jī)器中的rabbitmq
- #機(jī)器A
- service rabbitmq-server stop
- epmd -kill
- #機(jī)器B
- service rabbitmq-server stop
- epmd -kill
- #機(jī)器C
- service rabbitmq-server stop
- epmd -kill
移除rabbitmq配置記錄與存儲(chǔ)文件
- #位于 /var/lib/rabbitmq/mensia
- mv /var/lib/rabbitmq/mensia /var/lib/rabbitmq/mensia.bak
按順序啟動(dòng)所有機(jī)器中的rabbitmq
- #機(jī)器C
- service rabbitmq-server start
- #機(jī)器B
- service rabbitmq-server start
- #機(jī)器A
- service rabbitmq-server start
停止被加入集群節(jié)點(diǎn)app
- 比如A、B、C三臺(tái)機(jī)器,將B和C加入到A中去,需要執(zhí)行以下命令
- #機(jī)器B
- rabbitmqctl stop_app
- #機(jī)器C
- rabbitmqctl stop_app
建立集群
- 注意此處master為唯一沒(méi)有執(zhí)行rabbitmqctl stop_app的機(jī)器
- #機(jī)器B
- rabbitmqctl join_cluster rabbit@master
- #機(jī)器C
- rabbitmqctl join_cluster rabbit@master
啟動(dòng)集群
- #機(jī)器B
- rabbitmqctl start_app
- #機(jī)器C
- rabbitmqctl start_app
- 復(fù)制代碼
檢查集群狀態(tài)
在任意一臺(tái)機(jī)器上執(zhí)行rabbitmqctl cluster_status命令即可檢查,輸出包含集群中的節(jié)點(diǎn)與運(yùn)行中的節(jié)點(diǎn),兼以主機(jī)名標(biāo)志
添加集群配置
創(chuàng)建用戶(hù)
例子中創(chuàng)建了兩個(gè)用戶(hù) 添加用戶(hù)add_user,設(shè)置角色set_user_tags,添加rabbitmq虛擬主機(jī)add_vhost,設(shè)置訪問(wèn)權(quán)限set_permissions,以下是詳細(xì)用法
- 例子中創(chuàng)建了兩個(gè)用戶(hù) 添加用戶(hù)add_user,設(shè)置角色set_user_tags,添加rabbitmq虛擬主機(jī)add_vhost,設(shè)置訪問(wèn)權(quán)限set_permissions,以下是詳細(xì)用法
- # 創(chuàng)建第一個(gè)用戶(hù)
- /usr/sbin/rabbitmqctl add_user 用戶(hù)名 密碼
- /usr/sbin/rabbitmqctl set_user_tags 用戶(hù)名 administrator
- /usr/sbin/rabbitmqctl set_permissions -p / 用戶(hù)名 ".*" ".*" ".*"
- # 創(chuàng)建第二個(gè)用戶(hù)
- /usr/sbin/rabbitmqctl add_user 用戶(hù)名2 密碼
- /usr/sbin/rabbitmqctl set_user_tags 用戶(hù)名2 management
- /usr/sbin/rabbitmqctl add_vhost sip_ext
- /usr/sbin/rabbitmqctl set_permissions -p sip_ext 用戶(hù)名2 '.*' '.*' '.*'
- 復(fù)制代碼
- 備注:RabbitMQ 虛擬主機(jī),RabbitMQ 通過(guò)虛擬主機(jī)(vhost)來(lái)分發(fā)消息。擁有自己獨(dú)立的權(quán)限控制,不同的vhost之間是隔離的,單獨(dú)的。
- 權(quán)限控制的基本單位:vhost。
- 用戶(hù)只能訪問(wèn)與之綁定的vhost。
- vhost是AMQP中唯一無(wú)法通過(guò)協(xié)議來(lái)創(chuàng)建的基元。只能通過(guò)rabbitmqctl工具來(lái)創(chuàng)建。
打開(kāi)15672網(wǎng)頁(yè)管理端,訪問(wèn)mq
/usr/sbin/rabbitmq-plugins enable rabbitmq_management 備注:如果發(fā)現(xiàn)命令執(zhí)行完畢沒(méi)有打開(kāi)此服務(wù),15672端口沒(méi)有監(jiān)聽(tīng),則是由于沒(méi)有重啟mq導(dǎo)致的
在底部導(dǎo)入.json后綴的配置文件即可
http://localhost:4000/first-blog/rabbitmq.jpg
如果覆蓋了用戶(hù)需要使用以下命令修改mq用戶(hù)密碼 /usr/sbin/rabbitmqctl change_password 用戶(hù)名 密碼
修改節(jié)點(diǎn)類(lèi)型
- rabbitmqctl stop_app
- rabbitmqctl change_cluster_node_type dist
- rabbitmqctl change_cluster_node_type ram
- rabbitmqctl start_app
常用命令
4、常見(jiàn)故障
集群狀態(tài)異常
- rabbitmqctl cluster_status檢查集群健康狀態(tài),不正常節(jié)點(diǎn)重新加入集群
- 分析是否節(jié)點(diǎn)掛掉,手動(dòng)啟動(dòng)節(jié)點(diǎn)。
- 保證網(wǎng)絡(luò)連通正常
- 隊(duì)列阻塞、數(shù)據(jù)堆積
- 保證網(wǎng)絡(luò)連通正常
- 保證消費(fèi)者正常消費(fèi),消費(fèi)速度大于生產(chǎn)速度
- 保證服務(wù)器TCP連接限制合理
腦裂
按正確順序重啟集群
保證網(wǎng)絡(luò)連通正常
保證磁盤(pán)空間、cpu、內(nèi)存足夠
文章標(biāo)題:消息中間件:RabbitMQ原理、集群、基本運(yùn)維操作、常見(jiàn)故障處理
網(wǎng)頁(yè)路徑:http://www.dlmjj.cn/article/dpeodoi.html


咨詢(xún)
建站咨詢(xún)
