RabbitMQ實(shí)戰(zhàn)指南-朱忠華-電子工業(yè)出版社

RabbitMQ簡(jiǎn)介

消息中間件的作用:

  • 解耦
  • 冗余(存儲(chǔ))
  • 拓展性
  • 削峰
  • 可恢復(fù)性:處理消息的機(jī)器宕機(jī)之后,消息中間件可以存儲(chǔ)消息
  • 順序保證
  • 緩沖
  • 異步通信:消息中間件可以延遲消費(fèi)

RabbitMQ具體特點(diǎn):

  • 可靠性:消息確認(rèn)發(fā)布、傳輸確認(rèn),持久化
  • 靈活的路由
  • 拓展性:可以拓展為集群
  • 高可用:可以設(shè)置隊(duì)列鏡像,單一RabbitMQ掛機(jī)后,有鏡像提供服務(wù)
  • 多種協(xié)議
  • 多語(yǔ)言客戶端
  • 管理界面
  • 插件機(jī)制

RabbitMQ入門

GurFP0.png

RabbitMQ的模型架構(gòu)如圖,生產(chǎn)者Publisher通過TCP連接Connnection與RabbitMQ服務(wù)器Broker連接,每個(gè)Connection中有多個(gè)Channel。Broker服務(wù)器中有多個(gè)Virtual Host,每個(gè)Virtual Host各自獨(dú)立。Publisher發(fā)布消息Message到Exchange交換器,Message包含label(路由鍵)+payload(消息體),Binding上帶有綁定鍵,交換器根據(jù)自身性質(zhì)和路由鍵和綁定鍵決定將消息投遞到哪里。最終消息被保存在Queue隊(duì)列中,Consumer監(jiān)聽隊(duì)列獲得消息。

注意:

  • 生產(chǎn)者將消息傳到交換器后,交換器根據(jù)自身交換器類型和路由鍵、綁定鍵決定消息投遞的方向。
  • 只有隊(duì)列能存儲(chǔ)消息,消息到達(dá)隊(duì)列時(shí)已沒有l(wèi)abel了,只剩下消息體
  • 當(dāng)多個(gè)Consumer連接到同一個(gè)隊(duì)列時(shí),隊(duì)列上的消息將輪詢發(fā)給每個(gè)Consumer而不是每個(gè)消息復(fù)制多份發(fā)給每個(gè)Consumer,即每個(gè)消息只能被成功消費(fèi)一次

AMQP協(xié)議

Gu27y6.png

如上圖,AMQP協(xié)議每次發(fā)送數(shù)據(jù)時(shí)的指令。

客戶端開發(fā)向?qū)?/h2>

本章講了RabbitMQ Java客戶端的開發(fā),只摘錄我的部分理解在此。

創(chuàng)建RabbitMQ各個(gè)組件時(shí)可以有不同的參數(shù)。

  • Exchange交換器:type類型、durable是否持久化(持久化的Exchange重啟時(shí)不會(huì)消失),autoDelete自動(dòng)刪除(當(dāng)Exchange所綁定的queue都刪除后,自動(dòng)刪除Exchange,默認(rèn)不自動(dòng)刪除),internal是否內(nèi)置(若是,客戶端程序無(wú)法發(fā)信息到此交換器,只有交換器能發(fā)到此交換器)
  • queue隊(duì)列:durable是否持久化、exclusive排他(同Connection可見,其他Conntection不能創(chuàng)建同名隊(duì)列,Connection斷掉自動(dòng)刪除)、autoDelete自動(dòng)刪除(有消費(fèi)者訂閱過此隊(duì)列,之后所有消費(fèi)者取消訂閱,則刪除,生產(chǎn)者創(chuàng)建隊(duì)列后無(wú)客戶端連接是不會(huì)刪除的)

RabbitMQ的消息存儲(chǔ)在隊(duì)列中,交換器的使用并不真正耗費(fèi)服務(wù)器的性能,而隊(duì)列會(huì)。衡量RabbitMQ的QPS只需看隊(duì)列即可。

  • 消息投遞模式:發(fā)送消息處理指明交換器和路由鍵,還可以指定消息的一些屬性,如投遞模式為2時(shí),消息可持久化??梢栽O(shè)置消息的優(yōu)先級(jí)。
  • 消費(fèi)消息:有兩種模式,推模式Push和拉模式pull。消費(fèi)消息時(shí)可以設(shè)置是否自動(dòng)確認(rèn)。當(dāng)然,消息發(fā)送方也可以設(shè)置發(fā)送確認(rèn),RabbitMQ的exchange收到消息時(shí)可以回調(diào)發(fā)送方設(shè)置的監(jiān)聽。

消費(fèi)端的確認(rèn)和拒絕:消息訂閱有推和拉兩種模式,訂閱時(shí)可以設(shè)置是否自動(dòng)確認(rèn),自動(dòng)確認(rèn)的消息在RabbitMQ將消息發(fā)出時(shí)移除,非自動(dòng)確認(rèn)的消息需要客戶端手動(dòng)確認(rèn)。也可以拒絕該消息,拒絕時(shí)傳遞一個(gè)requeue參數(shù),可以設(shè)置是否將該消息重洗入隊(duì)等待發(fā)送,或者將其移除。

RabbitMQ進(jìn)階

本章講的是RabbitMQ的高級(jí)功能。

  • 交換器的屬性:
    • mandatory屬性為true時(shí),交換器如果找不到消息的路由,會(huì)將消息返回生產(chǎn)者,為false則丟棄
    • immediate參數(shù)為true時(shí),當(dāng)路由器發(fā)現(xiàn)隊(duì)列中不存在任何消費(fèi)者,則不投遞到該隊(duì)列。若所有隊(duì)列都無(wú)消費(fèi)者,則將消息返回生產(chǎn)者。RabbitMQ 3.0去掉了該屬性。

備份交換器AE:

  • 當(dāng)mandatory為true時(shí),無(wú)法路由的消息會(huì)返回生產(chǎn)者,為false時(shí),無(wú)法路由的消息會(huì)被丟棄。除了這兩者,還可以為交換器設(shè)置備份交換器,當(dāng)消息無(wú)法路由時(shí),會(huì)發(fā)送到備份交換器,備份交換器和mandatory一起使用,該參數(shù)無(wú)效。

過期時(shí)間TTL

  • 過期時(shí)間可以設(shè)置在隊(duì)列,也可以單獨(dú)設(shè)置在消息。一旦消息過期,就會(huì)變成“死信”。對(duì)于設(shè)置隊(duì)列的TTL,一旦消息過期則從隊(duì)列中抹去,而對(duì)于單獨(dú)設(shè)置TTL的消息,過期后不會(huì)馬上抹去,而是在消息投遞給消費(fèi)者之前判斷的。

死信交互器DLX(也稱死信隊(duì)列):

  • 當(dāng)消息變?yōu)樗佬胖?,他能被發(fā)送到死信交換器。
  • TTL和DLX可以做延時(shí)隊(duì)列
GtcFsg.png

持久化,RabbitMQ分為三部分:

  • 交換器持久化:交換器不持久化的話,重啟后元數(shù)據(jù)丟失,但消息不會(huì)丟失,因?yàn)橄⒋嬖陉?duì)列中
  • 隊(duì)列持久化:隊(duì)列不持久化的話,重啟后隊(duì)列會(huì)消失,消息也消失
  • 消息持久化:如果消息不持久化,那么重啟時(shí)消息會(huì)丟失,隊(duì)列持久化只能保證隊(duì)列的元數(shù)據(jù)不丟失,不能保證消息不丟失。

消息的可靠性:

  • 生產(chǎn)者確認(rèn):默認(rèn)情況下,生產(chǎn)者發(fā)送消息后不知道消息是否到達(dá)了RabbtMQ服務(wù)器??梢酝ㄟ^兩種方式確認(rèn)
    • 事務(wù)機(jī)制:如channel.txSelect將channel設(shè)置為事務(wù)模式,每次發(fā)送消息前都需要發(fā)送事務(wù)指令,嚴(yán)重影響性能
    • 發(fā)送方確認(rèn):類似tcp批量確認(rèn),每個(gè)消息都編號(hào),RabbitMQ會(huì)確認(rèn)一個(gè)序號(hào)表示這個(gè)序號(hào)之前的消息都已確認(rèn)。相比上面的事務(wù)機(jī)制,這里是異步的,而事務(wù)是同步確認(rèn)每一條消息的。
    • 當(dāng)然,生產(chǎn)者確認(rèn)只能保證消息傳遞到了服務(wù)器的交換器。如果消息沒有匹配的隊(duì)列,那么消息也會(huì)丟失,發(fā)送方可以配合mandatory參數(shù)或備份交換器解決沒有匹配隊(duì)列時(shí)的處理方式。
  • 消費(fèi)端要點(diǎn):默認(rèn)隊(duì)列中的消息會(huì)輪詢分發(fā)到訂閱同一隊(duì)列的消費(fèi)者,RabbitMQ并不管消費(fèi)者是否確認(rèn)了該消息,這會(huì)造成性能差的服務(wù)器處理過慢。可以使用channel.basicQos設(shè)定每個(gè)消費(fèi)者最多持有未確認(rèn)的消息數(shù)量,這種機(jī)制類似tcp的滑動(dòng)窗口,這種機(jī)制對(duì)于拉模式的消息消費(fèi)無(wú)效。
    • 消息順序性:消息的順序性是從存入隊(duì)列是開始的,不能認(rèn)為是從生產(chǎn)者發(fā)送時(shí)開始的,因?yàn)橛芯W(wǎng)絡(luò)抖動(dòng)。
    • 消息傳輸保障:
      • 最多一次:生產(chǎn)者隨意發(fā)送,消費(fèi)者隨意消費(fèi)
      • 最少一次:生產(chǎn)者開啟發(fā)送確認(rèn),生產(chǎn)者需要使用mandatory參數(shù)或備份交換器確保消息無(wú)法路由時(shí)能保存到隊(duì)列。消息和隊(duì)列都需要進(jìn)行持久化。消費(fèi)者需要手動(dòng)確認(rèn)消息。
      • 恰好一次:無(wú)法保證消息恰好一次被消費(fèi),因?yàn)榫W(wǎng)絡(luò)原因,消費(fèi)者消費(fèi)之后發(fā)送確認(rèn)消息時(shí)剛好網(wǎng)絡(luò)斷開,連接重新建立時(shí)消費(fèi)者會(huì)重新消費(fèi)到消息。RabbitMQ無(wú)法保證恰好一次,不僅RabbitMQ目前大多數(shù)主流的中間件都無(wú)法保證恰好一次。

RabbitMQ管理

RabbitMQ的應(yīng)用工具:

  • rabbitmqctl:命令行工具
  • rabbitmq_management插件:圖形化插件

多租戶與權(quán)限

  • 添加vhost:rabbitmqctl add_vhost myhost
  • 顯示vhost:rabbitmqctl list_vhosts
  • 刪除vhost:rabbitmqctl delete_host myhost
  • 權(quán)限配置到vhost:rabbitmqctl set_permissions [-p vhost] {user} {conf} {write} {read},如授予root用戶可訪問虛擬主機(jī)myhost并具備所有權(quán)限
    rabbitmqctl set_permissions -p myhost root ".*" ".*" ".*"
  • 清除權(quán)限:rabbitmqctl clear_permissions [-p vhost] {user}
  • 查看權(quán)限:rabbitmqctl list_user_permissions {user}

用戶管理

  • 創(chuàng)建用戶:rabbitmqctl add_user {username} {password}
  • 改密碼:rabbitmqctl change_password {username} {password}
  • 清除密碼:rabbitmqctl clear_password {username} {password}
  • 驗(yàn)證密碼:rabbitmqctl authenticate_user {username} {password}
  • 刪除用戶:rabbitmqctl delete_user {username}
  • 查看用戶:rabbitmqctl list_users
  • 設(shè)置角色:rabbitmqctl set_user_tags {username} {tags...}

用戶分為五種角色:

  • none:無(wú)任何角色,新創(chuàng)建的用戶默認(rèn)為none角色
  • management:可以訪問web管理頁(yè)面
  • policymaker:包含management的所有權(quán)限,并可以管理策略和參數(shù)
  • monitoring:包含management的所有權(quán)限,并可以看到所有連接、信道和結(jié)點(diǎn)
  • administrator:管理員

web端管理

  • 啟動(dòng)插件命令:rabbitmq-plugins enable rabbitmq_management
  • 查看插件使用情況:rabbitmq-plugins list

應(yīng)用與集群管理

  • 停止服務(wù):rabbitmqctl stop,rabbitmqctl stop_app,rabbitmqctl shutdown
  • 重置:rabbitmqctl reset還原rabbitmq到最初狀態(tài)

vhost、權(quán)限等都可以使用rabbitmqctl來(lái)創(chuàng)建,但交換器、隊(duì)列和綁定關(guān)系卻無(wú)法用rabbitmqctl來(lái)創(chuàng)建,只能通過web管理界面創(chuàng)建。然而,rabbitmq management還提供了命令行rabbitmqadmin來(lái)解決這個(gè)問題。如查看隊(duì)列中的消息

rabbitmqadmin get queue=myqueue

rabbitmq management還提供了http api接口來(lái)方便調(diào)用。如創(chuàng)建一個(gè)隊(duì)列,可以使用PUT方法調(diào)用/api/queues/vhost/name接口來(lái)實(shí)現(xiàn)。

RabbitMQ配置

三種方式配置:

  • 環(huán)境變量:如RABBITMQ_NODENAME=rabbit@node2 rabbitmq-server -detached,環(huán)境變量也可配置在RABBITMQ_HOME/etc/rabbitmq/rabbitmq-env.conf中
  • 配置文件:配置文件位于/opt/rabbitmq/etc/rabbitmq/rabbitmq.config
  • 運(yùn)行時(shí)參數(shù)和策略:可以通過rabbitmqctl或management插件提供的http api來(lái)設(shè)置,如rabbitmqctl set_parameter

RabbitMQ運(yùn)維

本章主要將集群的搭建和運(yùn)維

跨越集群的界限

RabbitMQ可以通過3種方式實(shí)現(xiàn)分布式部署:

  • 集群
  • Federation:該插件的目的是使RabbitMQ在不同的Broker結(jié)點(diǎn)之間進(jìn)行消息通信而無(wú)需創(chuàng)建集群
  • Shovel:該插件能夠可靠、持續(xù)地從一個(gè)Broker中的隊(duì)列拉取數(shù)據(jù)并轉(zhuǎn)發(fā)至另一個(gè)Broker中的交換器。

RabbitMQ高階

本章是將RabbitMQ的內(nèi)部原理的,需要熟悉

流控

RabbitMQ可以對(duì)內(nèi)存和磁盤使用量設(shè)置閾值,達(dá)到閾值后,生產(chǎn)者將阻塞。這是全局流控,面向所有連接的。當(dāng)然RabbitMQ也可以面向單個(gè)Connection進(jìn)行流控。

RabbitMQ使用一種基于信用證算法的流控機(jī)制來(lái)限制發(fā)送消息的速率。

鏡像隊(duì)列

生產(chǎn)者發(fā)送消息時(shí),會(huì)將消息都發(fā)送到各個(gè)slave,除發(fā)送消息外的所有動(dòng)作都只會(huì)向master發(fā)送,然后再由master將命令執(zhí)行的結(jié)果廣播給各個(gè)slave。

網(wǎng)絡(luò)分區(qū)

在局域網(wǎng)環(huán)境下,網(wǎng)絡(luò)設(shè)備出現(xiàn)故障時(shí)也會(huì)導(dǎo)致網(wǎng)絡(luò)分區(qū)。當(dāng)出現(xiàn)網(wǎng)絡(luò)分區(qū)時(shí),不同分區(qū)里的結(jié)點(diǎn)會(huì)認(rèn)為不屬于自身所在分區(qū)的結(jié)點(diǎn)都已經(jīng)掛了。如果原集群中配置了鏡像隊(duì)列,每個(gè)網(wǎng)絡(luò)分區(qū)中都會(huì)出現(xiàn)一個(gè)master結(jié)點(diǎn)。

RabbitMQ拓展

消息追蹤:Firehose

負(fù)載均衡:輪詢、加權(quán)輪詢、隨機(jī)、加權(quán)隨機(jī)、源地址哈希、最小連接數(shù)

使用HAProxy實(shí)現(xiàn)負(fù)載均衡

使用Keepalived實(shí)現(xiàn)高考可靠負(fù)載均衡

使用keepalived+LVS實(shí)現(xiàn)負(fù)載均衡

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 什么叫消息隊(duì)列? 消息(Message)是指在應(yīng)用間傳送的數(shù)據(jù)。消息可以非常簡(jiǎn)單,比如只包含文本字符串,也可以更復(fù)...
    Agile_dev閱讀 2,438評(píng)論 0 24
  • 1.connection可以用來(lái)創(chuàng)建多個(gè)channel實(shí)例,但是channel實(shí)例不能再線程間共享,應(yīng)用程序應(yīng)該為...
    神煩2閱讀 544評(píng)論 0 1
  • RabbitMQ采用Erlang編寫,需安裝語(yǔ)言庫(kù)才能運(yùn)行RabbitMQ代理服務(wù)器。AMQP:高級(jí)消息隊(duì)列協(xié)議。...
    JAVA覓音閣閱讀 4,018評(píng)論 0 7
  • rabbitmqctl 命令的一些基礎(chǔ)操作 rabbitmqctl add vhost {vhostName} -...
    _大叔_閱讀 9,485評(píng)論 0 1
  • RabbitMQ 原理介紹及安裝部署 標(biāo)簽:RabbitMQ 安裝 簡(jiǎn)介 RabbitMQ 是一個(gè)用 Erlang...
    神仙CGod閱讀 8,727評(píng)論 0 60

友情鏈接更多精彩內(nèi)容