您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)RabbitMQ如何高效部署分布式消息隊列,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
一、天降奇兵
1.消息隊列使用消息將應(yīng)用程序連接起來。這些消息通過像RabbitMQ這樣的消息代理服務(wù)器在應(yīng)用程序之間路由
2.RabbitMQ優(yōu)勢:
除Qpid外,唯一實現(xiàn)了AMQP標(biāo)準(zhǔn)的代理服務(wù)器
由于Erlang,RabbitMQ集群不可思議的簡單
比其他更可靠,更能防止崩潰
3.檢查服務(wù)器狀態(tài):rabbitmqctl status
二、理解消息通信
A.消費者和生產(chǎn)者
1.RabbitMQ不是快餐車而是消息投遞服務(wù),在應(yīng)用程序和服務(wù)器之間扮演著路由器的角色
2.生產(chǎn)者(producer)創(chuàng)建消息,然后發(fā)布(發(fā)送)到代理服務(wù)器(RabbitMQ)。消息包含有效載荷(payload)和標(biāo)簽(label)
有效載荷就是你要傳輸?shù)臄?shù)據(jù),可以是任何內(nèi)容
標(biāo)簽描述了有效載荷,并用它來決定誰將獲得消息的拷貝
3.消息者,連接到代理服務(wù)器上,并訂閱到隊列(queue)上,當(dāng)消費者接收到消息時,它只得到消息的一部分:有效載荷
4.生產(chǎn)者創(chuàng)建消息,消費者接收這些消息。應(yīng)用程序可以作為生產(chǎn)者,向其他應(yīng)用程序發(fā)送消息?;蛘咦鳛橐粋€消費者,接收消息。也可以在兩者之間進(jìn)行切換。不過必須先建立一條信道(channel)
5.在應(yīng)用程序和Rabbit代理服務(wù)器之間創(chuàng)建一條TCP連接。一旦TCP連接找開(通過了認(rèn)證),應(yīng)用程序就可以創(chuàng)建一條AMQP信道。信道是建立在“真實的”TCP連接內(nèi)的虛擬連接,每條信道都會被指派一個唯一ID
B.從底部開始構(gòu)造:隊列
1.AMQP消息路由必須有三部分:交換器、隊列和綁定
生產(chǎn)者把消息發(fā)布到交換器上;消息最終到達(dá)隊列,并被消費者接收;綁定決定了消息如何從路由器路由到特定的隊列
2.隊列就如同具名郵箱,消息最終達(dá)到隊列中并等待消費,消費者通過以下兩種方式從特定隊列中接收消息:
通過AMQP的basic.consume命令訂閱:如果消費者處理隊列消息,并且/或者需要在消息一到達(dá)隊列時就自動接收的話,應(yīng)該使用這個命令
basic.get命令:會訂閱消息,獲得單條消息,然后取消訂閱,不要放在一個循環(huán)中來代替basic.consume,會影響性能
3.當(dāng)Rabbit隊列擁有多個消費者時,隊列收到的消息將以循環(huán)(round-robin)的方式發(fā)送給消費者,每條消息只會發(fā)送給一個訂閱的消費者
4.消費者必須通過AMQP的basic.ack顯示地向RabbitMQ發(fā)送一個確認(rèn),或者在訂閱到隊列的時候就將auto_ack參數(shù)設(shè)置為true。消費者對消息的確認(rèn)和告訴生產(chǎn)者消息已經(jīng)被接收了這兩件事毫不相關(guān)。消費者通過確認(rèn)命令告訴RabbitMQ它已經(jīng)正確地接收了消息,同時RabbitMQ才能安全地把消息從隊列中刪除
5.如果消費者收到一條消息,然后確認(rèn)之前從Rabbit斷開連接(或者從隊列上取消訂閱),RabbitMQ會認(rèn)為這條消息沒有分發(fā),然后重新分發(fā)給下一個訂閱的消費者
6.拒絕消息:
把消費者從RabbitMQ服務(wù)器斷開連接:會導(dǎo)致RabbitMQ自動重新把消息入隊并發(fā)送給另一個消費者,缺點是連接/斷開連接的方式會額外增加RabbitMQ的負(fù)擔(dān)
RabbitMQ2.0.0以上版本可以使用AMQP的basic.reject命令
7.消費者和生產(chǎn)者都能使用AMQP的queue.declare命令來創(chuàng)建隊列
如果消費者在同一條信道上訂閱了一另一個隊列的話,就無法再聲明隊列了,必須先取消訂閱并將信道置為“傳輸”模式
消費者訂閱隊列時需要隊列名稱,并在創(chuàng)建綁定時也需要指定隊列名稱
exclusive:如果設(shè)置為true,隊列變成私有的,只有自己的應(yīng)用程序才能消費隊列
auto-delete:當(dāng)最后一個消費者取消訂閱的時候,隊列就會自動移除
passive:設(shè)置為true后,如果隊列存在,queue.declare就會成功返回;如果不存在,會返回錯誤
8.如果不能承擔(dān)得起消息進(jìn)入“黑洞”而丟失的話,生產(chǎn)者和消費者都應(yīng)該嘗試去創(chuàng)建隊列;否則可以只讓消費者來聲明隊列
C.聯(lián)合起來:交換器和綁定
1.當(dāng)你把消息發(fā)送到代理服務(wù)器時,消息將擁有一個路由鍵——即使是空的——RabbitMQ也會將其和綁定使用的路由鍵進(jìn)行匹配。如果相匹配的話,那么消息將會投遞到該隊列。如果不匹配任何綁定模式的話,消息將進(jìn)入“黑洞”
2.交換器和綁定可以完成不同的使用場景;對于發(fā)送消息給服務(wù)器的發(fā)布者,不需要關(guān)心服務(wù)器另一端(整個消息處理環(huán)節(jié)中的隊列和消費者)的邏輯
3.處理投遞到多個隊列的協(xié)議:
direct交換器:如果路由鍵匹配的話,消息就投遞到對應(yīng)的隊列。服務(wù)器必須實現(xiàn)direct類型交換器,包含一個空白字符串名稱的默認(rèn)交換器。當(dāng)聲明一個隊列時,它會自動 綁定到默認(rèn)交換器,并以聊表名稱作為路由鍵 $channel->basic_publish(消息內(nèi)容,默認(rèn)交換器,路由鍵)
fanout交換器:會將收到的消息廣播到綁定的隊列上,當(dāng)發(fā)送一條消息到fanout交換器時,會把消息投遞給所有附加在此交換器上的隊列
topic交換器:使得來自不同源頭的消息能夠到達(dá)同一個隊列
D.多租戶模式:虛擬主機(jī)和隔離
1.每一個RabbitMQ服務(wù)器都能創(chuàng)建虛擬消息服務(wù)器,稱為虛擬機(jī)(vhost),每一個vhost本質(zhì)上是一個mini版的RabbitMQ服務(wù)器,擁有自己的隊列、交換器和綁定,以及權(quán)限機(jī)制
2.在Rabbit里創(chuàng)建一個用戶時,用戶通常會被指派給至少一個vhost,并且只能訪問被指派vhost內(nèi)的隊列、交換器和綁定,在設(shè)計消息通信架構(gòu)時,記住vhost之間是絕對隔離的,在集群上創(chuàng)建vhost時,整個集群都會創(chuàng)建該vhost
3.創(chuàng)建、刪除、查看:
rabbitmqctl add_vhost [vhost_name]
rabbitmqctl delete_vhost [vhost_name]
rabbitmqctl list_vhosts
E.持久化和策略
1.隊列和交換器的durable屬性設(shè)為true,決定RabbitMQ在崩潰或重啟之后重新創(chuàng)建隊列(或交換器)
2.消息想要從Rabbit崩潰中恢復(fù),必須:
把它的投遞模式(delivery mode)選項設(shè)置為2(持久)
發(fā)送到持久化的交換器
到達(dá)持久化的隊列
3.確保持久性消息能恢復(fù)的方式是,將它們寫入磁盤上的一個持久化日志文件,當(dāng)發(fā)布一條持久性消息到持久交換器上時,Rabbit會在消息提交到日志文件后才發(fā)送響應(yīng),之后這條消息如果路由到了非持久隊列的話,它會自動從持久性日志中移除
4.持久性的劣勢:性能變慢,內(nèi)建集群中工作得不好
5.對于關(guān)鍵消息使用持久化機(jī)制
6.AMQP事務(wù)會大大降低Rabbit的性能,Rabbit團(tuán)隊使用發(fā)送方確認(rèn)模式,將信道設(shè)置成confirm模式,是異步的
https://github.com/zhangyue0503/rabbitmq/tree/master/2
三、運行和管理Rabbit
A.服務(wù)器管理
1.節(jié)點:描述的是一個Erlang節(jié)點運行著一個Erlang應(yīng)用程序,多個應(yīng)用程序可以運行在同一個節(jié)點之上,RabbitMQ節(jié)點指的是RabbitMQ應(yīng)用程序和其所在的Erlang節(jié)點
2.rabbitmq-server 啟動;rabbitmqctl stop 關(guān)閉;
3.配置文件rabbitmq-config,vm_memory_high_watermark指定可消耗的內(nèi)存,十進(jìn)制數(shù)字,0.4表示為40%
B.請求許可
1.用戶相關(guān)命令:
rabbitmqctl add_user 用戶名 密碼
rabbitmqctl delete_user 用戶名
rabbitmqctl list_users
rabbitmqctl change_password 用戶名 新密碼
2.訪問控制條目組成:被授予訪問權(quán)限的用戶、權(quán)限控制應(yīng)用的vhost、需要授予的讀/寫/配置權(quán)限的組合、權(quán)限范圍
3.訪問控制條目是無法跨越vhost的
4.訪問權(quán)限命令:
rabbitmqctl set_permissions -p [vhost] [user] "配置" "寫" "讀",".*"匹配任何隊列和交換器,"check-.*"匹配以check-開頭的隊列和交換器,""不匹配隊列和交換器
rabbitmqctl list_permissions -p [vhost] 驗證權(quán)限是否正確
rabbitmqctl clear_permissions -p [vhost] [user]移除用戶在vhost上的權(quán)限
rabbitmqctl list_user_permissions [user]查看用戶在所有vhost上的權(quán)限
C.檢查
1.相關(guān)命令:
rabbitmqctl list_queues -p [vhost] [name名稱 messages消息數(shù)目 consumers消費者數(shù)目 memory內(nèi)存使用等……]列出所有隊列及隊列里的消息數(shù)目
rabbitmqctl list_exchanges 查看交換器信息
rabbitmqctl list_bindings 查看綁定信息
2.日志
*-sasl.log,SASL(系統(tǒng)應(yīng)用程序支持庫)是庫的集合,幫助開發(fā)Erlang應(yīng)用時,提供一系列標(biāo)準(zhǔn)
輪換日志:rabbitmqctl rotate_logs shuffix,shuffix通常是數(shù)字,添加到被輪換日志文件的末尾
D.修復(fù)Rabbit:疑難解答
1.RabbitMQ使用Mnesia數(shù)據(jù)庫存儲隊列、交換器、綁定等信息
https://github.com/zhangyue0503/rabbitmq/tree/master/3
四、解決Rabbit相關(guān)問題:編碼與模式
A.解耦
1.異步狀態(tài)思維(分離請求和動作):接收請求->RabbitMQ->處理請求(入庫)
2.自動輪詢(round-robin)可代替負(fù)載均衡
3.零成本API:語言不應(yīng)成為枷鎖
4.如何將應(yīng)用切分?應(yīng)用程序的哪部分是訂單接收者,哪部分是訂單處理者?
B.發(fā)后即忘模型
1.創(chuàng)建了任務(wù),放置到交換器上,并讓你的應(yīng)用程序返回繼續(xù)工作
2.匹配該模式的兩種一般類型的任務(wù):
批處理(batch processing):針對大型數(shù)據(jù)集合的工作或者轉(zhuǎn)換
通知(notifications):以發(fā)生事件的描述
3.RabbitMQ使用“.”作為標(biāo)記中不同部分的分隔符;no_ack=false告訴RabbitMQ要顯示確認(rèn)收到的消息,這將暫停從隊列發(fā)送新的消息過來,直到收到的最后一條消息處理完成并發(fā)送確認(rèn)消息為止;
C.用RabbitMQ實現(xiàn)RPC并等待響應(yīng)
1.使用reply_to作為發(fā)布應(yīng)答消息的目的地,同時發(fā)布的時候無須指定交換器
2.exclusive=true,確保只有自己才能讀取隊列上的數(shù)據(jù);auto_delete,接收完消息后斷開隊列的連接時,Rabbit會自動將隊列刪除
https://github.com/zhangyue0503/rabbitmq/tree/master/4
五、集群并處理失敗
A.集群架構(gòu)
1.集群只會在單個節(jié)點上而不是所有節(jié)點上創(chuàng)建完整的隊列信息(元數(shù)據(jù)、狀態(tài)、內(nèi)容)
2.交換器只是一個名稱和一個隊列的綁定列表,信道才是真正的路由器
3.使用AMQP事務(wù),在消息路由到隊列之前會一直阻塞;或者使用發(fā)送方確認(rèn)(publisher confirm)模式來記錄連接中斷時尚未被確認(rèn)的消息。這兩種解決方案可以幫助在節(jié)點故障并且目的隊列不復(fù)存在時檢測到消息無法路由的情況
4.單節(jié)點必須是磁盤類型節(jié)點,否則一重啟所有配置信息都會丟失;集群允許只有一個節(jié)點是磁盤節(jié)點,其他可以是內(nèi)存節(jié)點,當(dāng)磁盤節(jié)點崩潰后,不能對隊列進(jìn)行操作;可以設(shè)置兩個磁盤節(jié)點;添加內(nèi)在節(jié)點時,需要確保告知所有的磁盤節(jié)點;
B.單機(jī)集群
1.需要修改環(huán)境變量RABBITMQ_NODE_PORT和RABBITMQ_NODENAME,如RABBITMQ_NODE_PORT=5763和RABBITMQ_NODENAME=rabbit_1,然后rabbitmq-server -detached
2.rabbitmqctl -n rabbit_1@主機(jī)名 stop_app,然后再reset
3.rabbitmqctl -n rabbit_1@主機(jī)名 join_cluster rabbit@主機(jī)名
4.rabbitmqctl -n rabbit_1@主機(jī)名 start_app
5.rabbitmqctl cluster_status
6.-n表示指定節(jié)點而非默認(rèn)節(jié)點上執(zhí)行命令
C.將節(jié)點分布到更多的機(jī)器上
1.需要復(fù)制找到.erlang.cookie,復(fù)制其中的字符串到其他節(jié)點上,然后再進(jìn)行join_cluster
2.刪除節(jié)點,直接通過reset命令
D.鏡像隊列和保留消息
1.鏡像隊列的主拷貝僅存在于一個節(jié)點(主隊列,master),在其他的集群上擁有從隊列(slave)拷貝
2.xa-ha-policy和xa-ha-policy-params
https://github.com/zhangyue0503/rabbitmq/tree/master/5
六、從故障中恢復(fù)
A.為Rabbit做負(fù)載均衡
1.當(dāng)為Rabbit添加負(fù)載均衡器時,集群節(jié)點就作為負(fù)載均衡器背后的服務(wù)器,而你的生產(chǎn)者和消費者就是客戶,應(yīng)用程序只需知道負(fù)載均衡器的前端IP;負(fù)載均衡器會以最小的連接負(fù)載透明地將客戶端連接到集群節(jié)點
B.連接丟失和故障轉(zhuǎn)移
1.應(yīng)該總是將故障轉(zhuǎn)移視為連接到了一個完全 無關(guān)的RabbitMQ服務(wù)器,而不是有著共享狀態(tài)的集群節(jié)點,不論節(jié)點故障什么時候發(fā)生,在檢測到故障并進(jìn)行重邊之后的首要任務(wù)是構(gòu)造交換器、隊列和綁定
七、warren和Shovel:故障轉(zhuǎn)移和復(fù)制
A.warren:另一種集群方式
1.一個warren是指一對主/備獨立服務(wù)器,并前置一臺負(fù)載均衡器來處理故障轉(zhuǎn)移。這是真正的無共享架構(gòu),主和備之間沒有協(xié)作。
B.遠(yuǎn)距離通信和復(fù)制
1.Shovel是RabbitMQ的一個插件,能夠定義RabbitMQ上的隊列和另一個RabbitMQ上的交換器之間的關(guān)系
2.安裝插件:rabbitmq-plugins enable rabbitmq_shovel
八、從Web端管理RabbitMQ
A.超越rabbitmqctl:RabbitMQ Management插件
1.rabbitmq-plugins enable rabbitmq_management,http://localhost:15672/mgmt/
2.rabbitmqadmin腳本:wget http://localhost:15672/cli/rabbitmqadmin
九、使用REST API控制Rabbit
1.http://localhost:15672/api,如http://localhost:15672/api/users
十、監(jiān)控
1.四種整型退出代碼:0-OK,1-WARNING,2-CRITICAL,3-UNKNOWN
十一、提升性能,保障安全
1.如果可以接受丟失消息,將delivery-mode設(shè)置為1,設(shè)置為2將持久化,消息寫寫到磁盤上,降低速度
2.no-ack為true,服務(wù)器會在消息發(fā)送給客戶端后自動將其出隊
3.direct交換器和fanout交換器的差別在于后者在查詢rabbit_route表時忽略了路由鍵;topic交換器相比前兩者會占用更多的內(nèi)存
4.消息中的mandatory和immediate標(biāo)記為false的話,會以異步方式投遞消息
5.RabbitMQ被優(yōu)化為盡可能快地向消費者投遞消息,應(yīng)該盡可能讓隊列保持為空
6.如果隊列聲明中durable為true的話,會在表rabbit_queue和rabbit_durable_queue添加隊列記錄,否則只會在rabbit_queue中存放記錄
十二、擴(kuò)展RabbitMQ
1.http://www.rabbitmq.com/plugins.html
2.插件啟用:rabbitmq-plugins enable xxxxx;移除插件:rabbitmq-plugins disable xxx
關(guān)于“RabbitMQ如何高效部署分布式消息隊列”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。