消息隊列 - RabbitMQ

消息隊列 - RabbitMQ

    • 1. 初識 MQ
      • 1.1 同步調用
      • 1.2 異步調用
      • 1.3.技術選型
    • 2. RabbitMQ
      • 2.1 安裝
      • 2.2 收發信息
        • 2.2.1 交換機(Exchange)
        • 2.2.2 隊列
        • 2.2.3 綁定關系
        • 2.2.4 發送消息
      • 2.3 數據隔離

1. 初識 MQ

微服務一旦拆分,必然涉及到服務之間的相互調用,之前講到的基于 OpenFeign 的調用。這種調用中,調用者發起請求后需要等待服務提供者執行業務返回結果后,才能繼續執行后面的業務。也就是說調用者在調用過程中處于阻塞狀態,因此我們稱這種調用方式為同步調用,也可以叫同步通訊。但在很多場景下,我們可能需要采用異步通訊的方式,為什么呢?

兩種方式的區別:

  • 同步通訊:就如同打視頻電話,雙方的交互都是實時的。因此同一時刻你只能跟一個人打視頻電話。
  • 異步通訊:就如同發微信聊天,雙方的交互不是實時的,你不需要立刻給對方回應。因此你可以多線操作,同時跟多人聊天。

兩種方式各有優劣,打電話可以立即得到響應,但是你卻不能跟多個人同時通話。發微信可以同時與多個人收發微信,但是往往響應會有延遲。

所以,如果我們的業務需要實時得到服務提供方的響應,則應該選擇同步通訊(同步調用)。而如果我們追求更高的效率,并且不需要實時響應,則應該選擇異步通訊(異步調用)。

1.1 同步調用

我們以注冊成功后郵件通知為例

image-20231207225257184

同步調用的業務流程是:

  • 發送注冊請求
  • 注冊成功將信息存入數據庫
  • 發送郵件通知
  • 返回成功信息

這樣的業務流程會存在下面三個問題

一、性能低

由于同步調用,調用者需要等待服務提供者執行完返回結果后,才能繼續向下執行,也就是說每次遠程調用,調用者都是阻塞等待狀態。最終整個業務的響應時長就是每次遠程調用的執行時長之和:100+100+300+50 = 550ms

二、擴展性差

比如需要添加短信通知,需要在代碼中添加短信服務的遠程調用代碼。

三、級聯失效

在這個案例中,注冊成功了,但是郵件通知服務出現了問題拋出了錯誤會讓存入數據庫的信息回滾導致整個注冊業務失敗。

需要解決這些問題就需要用異步調用的方式來代替同步調用

1.2 異步調用

異步調用方式其實就是基于消息通知的方式,一般包含三個角色:

  • 消息發送者:投遞消息的人,就是原來的調用方
  • 消息Broker:管理、暫存、轉發消息,你可以把它理解成微信服務器
  • 消息接收者:接收和處理消息的人,就是原來的服務提供方

image-20231207230036497

在異步調用中,發送者不再直接同步調用接收者的業務接口,而是發送一條消息投遞給消息Broker。然后接收者根據自己的需求從消息Broker那里訂閱消息。每當發送方發送消息后,接受者都能獲取消息并處理。
這樣,發送消息的人和接收消息的人就完全解耦了。

還是以注冊通知為例:

image-20231207230635303

將遠程調用邏輯刪除,改為發送一條消息到Broker。而相關的微服務都可以訂閱消息通知,一旦消息到達Broker,則會分發給每一個訂閱了的微服務,處理各自的業務。

后續需要添加短信通知也只需要添加一個短信服務訂閱消息即可。

而且注冊服務的耗時也和其他服務無關。

綜上,異步調用的優勢包括:

  • 耦合度更低
  • 性能更好
  • 業務拓展性強
  • 故障隔離,避免級聯失敗

當然,異步通信也并非完美無缺,它存在下列缺點:

  • 完全依賴于Broker的可靠性、安全性和性能
  • 架構復雜,后期維護和調試麻煩

1.3.技術選型

消息Broker,目前常見的實現方案就是消息隊列(MessageQueue),簡稱為MQ.
目比較常見的MQ實現:

  • ActiveMQ
  • RabbitMQ
  • RocketMQ
  • Kafka

幾種常見MQ的對比:

RabbitMQActiveMQRocketMQKafka
公司/社區RabbitApache阿里Apache
開發語言ErlangJavaJavaScala&Java
協議支持AMQP,XMPP,SMTP,STOMPOpenWire,STOMP,REST,XMPP,AMQP自定義協議自定義協議
可用性一般
單機吞吐量一般非常高
消息延遲微秒級毫秒級毫秒級毫秒以內
消息可靠性一般一般

追求可用性:Kafka、 RocketMQ 、RabbitMQ
追求可靠性:RabbitMQ、RocketMQ
追求吞吐能力:RocketMQ、Kafka
追求消息低延遲:RabbitMQ、Kafka

2. RabbitMQ

RabbitMQ 是一個開源的消息中間件(Message Broker),用于在分布式系統中傳遞消息。它實現了高級消息隊列協議(AMQP),這是一種網絡協議,用于在應用程序之間傳遞消息。

以下是 RabbitMQ 的一些主要特性和概念:

  1. 消息隊列: RabbitMQ 提供了一個消息隊列,允許不同的應用程序通過消息進行通信。發送方將消息放入隊列,而接收方則從隊列中獲取消息。
  2. 發布/訂閱模型: RabbitMQ 支持發布/訂閱模型,其中一個應用程序(發布者)發布消息,而多個應用程序(訂閱者)可以訂閱并接收這些消息。
  3. 可靠性: RabbitMQ 提供了持久性,確保即使在代理重新啟動后,隊列和消息也不會丟失。
  4. 靈活的路由: RabbitMQ 具有靈活的路由機制,可以根據不同的條件將消息路由到不同的隊列。
  5. 多協議支持: RabbitMQ 支持多種消息傳遞協議,包括 AMQP、STOMP、MQTT 等。
  6. 插件系統: RabbitMQ 具有豐富的插件系統,可以通過插件擴展其功能,如集群、身份驗證、可視化工具等。
  7. 可視化管理界面: RabbitMQ 提供了一個易于使用的管理界面,允許用戶監視和管理隊列、交換機等組件。
  8. 集群支持: RabbitMQ 支持構建集群,以提高可用性和性能。
  9. 消息確認: 客戶端可以向 RabbitMQ 確認已成功處理消息,確保消息不會因為消費者故障而丟失。
  10. 死信隊列: RabbitMQ 支持死信隊列,用于處理無法被消費的消息。

2.1 安裝

這里介紹 Docker 安裝 RabbitMQ 的過程。

2.1.1 拉取鏡像

docker pull rabbitmq:management #  拉取帶有web界面的鏡像

image-20231207210107857

2.1.2 啟動容器

docker run -e RABBITMQ_DEFAULT_USER=root -e RABBITMQ_DEFAULT_PASS=root --name mq --hostname q -p 15672:15672 -p 5672:5672 -d rabbitmq:management
# -e RABBITMQ_DEFAULT_USER=root 用戶名
# -e RABBITMQ_DEFAULT_PASS=root 密碼

端口介紹:

  • 4369/tcp: Erlang Port Mapper Daemon (EPMD)端口,用于Erlang節點之間的通信。
  • 5671/tcp: AMQP over TLS/SSL端口,用于安全的AMQP連接。
  • 5672/tcp: 默認的AMQP端口,用于客戶端連接和消息傳遞。
  • 15671/tcp: RabbitMQ Management插件的安全AMQP端口。
  • 25672/tcp: 集群端口,用于Erlang分布式節點之間的內部通信。
  • 15672/tcp: RabbitMQ Management插件的Web管理界面端口,通過Web界面進行RabbitMQ的管理。

image-20231207231928650

2.1.3 訪問管理頁面

http://ip地址:15672

image-20231207232019327

RabbitMQ對應的架構如圖:

image-20231208134920751

其中包含幾個角色:

  • publisher:生產者,也就是發送消息的一方
  • consumer:消費者,也就是消費消息的一方
  • queue:隊列,存儲消息。生產者投遞的消息會暫存在消息隊列中,等待消費者處理
  • exchange:交換機,負責消息路由。生產者發送的消息由交換機決定投遞到哪個隊列。
  • virtual host:虛擬主機,起到數據隔離的作用。每個虛擬主機相互獨立,有各自的exchange、queue

2.2 收發信息

2.2.1 交換機(Exchange)

打開Exchanges選項,可以看到RabbitMQ預定義了7種交換機,這7種交換機有4種類型。
image-20231207232533500

關于交換機類型的簡介:

  1. Direct Exchange(直連交換機):

    直連交換機是最簡單的交換機類型。

    它將消息路由到與消息中的路由鍵完全匹配的隊列中。

    在消息生產者指定的路由鍵和隊列的綁定鍵完全相同時,消息將被發送到相應的隊列。

  2. Fanout Exchange(扇出交換機):

    • 扇出交換機將消息廣播到與交換機綁定的所有隊列,忽略路由鍵。
    • 適用于廣播消息給多個消費者的場景,不關心消息的具體內容。
  3. Topic Exchange(主題交換機):

    • 主題交換機通過匹配路由鍵和模式的方式來路由消息到隊列。
    • 路由鍵可以包含通配符 *(匹配一個單詞)和 #(匹配零個或多個單詞),允許更復雜的路由規則。
  4. Headers Exchange(頭交換機):

    • 頭交換機使用消息的頭部信息而不是路由鍵來決定如何路由消息。
    • 在綁定隊列時指定一組鍵值對(headers),只有當消息的頭部信息與這些鍵值對完全匹配時,消息才會被路由到隊列。

關于預定義的7種交換機簡介:

  1. AMQP default:
    • 這是一個直連交換機,是 RabbitMQ 的默認交換機。
    • 當消息的路由鍵與隊列的綁定鍵完全匹配時,消息將被發送到相應的隊列。
  2. amq.direct:
    • 也是一個直連交換機。
    • 類似于 AMQP 默認交換機,將消息路由到與消息中的路由鍵完全匹配的隊列。
  3. amq.fanout:
    • 是一個扇出交換機。
    • 將消息廣播到與交換機綁定的所有隊列,忽略路由鍵。
  4. amq.headers:
    • 是一個頭交換機。
    • 使用消息的頭部信息而不是路由鍵來決定如何路由消息。在綁定隊列時指定一組鍵值對(headers)。
  5. amq.match:
    • 是一個主題交換機。
    • 通過匹配路由鍵和模式的方式來路由消息到隊列。支持更復雜的路由規則。
  6. amq.rabbitmq.trace:
    • 這是一個專用于消息追蹤的交換機。
    • 用于在 RabbitMQ 中追蹤消息的流動,通常不用于常規消息傳遞。
  7. amq.topic:
    • 也是一個主題交換機。
    • 通過匹配路由鍵和模式的方式來路由消息到隊列。類似于 amq.match,支持更復雜的路由規則。
2.2.2 隊列

打開Queues選項卡,新建一個隊列:

image-20231208133420881

image-20231208133500631

2.2.3 綁定關系

點擊 amq.fanout 交換機

image-20231208133656411

綁定隊列 queue1

image-20231208133615746

image-20231208133641084

2.2.4 發送消息

點擊 amq.fanout 交換機

image-20231208133925673

發送消息

image-20231208133915372

隊列成功收到消息

image-20231208133941568

image-20231208133958825

2.3 數據隔離

RabbitMQ 使用 virtual host 實現數據隔離

新建一個虛擬主機

image-20231208140406859

添加一個用戶

image-20231208140459340

現在用戶test還沒有能訪問的虛擬主機

image-20231208140549326

切換登錄用戶test后無法獲取沒有訪問權限的虛擬主機的隊列消息。

image-20231208135723332

點擊test為用戶添加虛擬主機

image-20231208140634479

image-20231208140658453

右上角 虛擬主機切換為 /test 看不到其他虛擬主機的消息隊列,這就是基于virtual host 的隔離效果。

image-20231208140741872

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/207034.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/207034.shtml
英文地址,請注明出處:http://en.pswp.cn/news/207034.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL六 | 存儲引擎

目錄 存儲引擎 存儲引擎特點 存儲引擎選擇 Innodb與MyISAM區別 存儲引擎 默認存儲引擎:InnoDB show engines;#展示當前數據庫支持的存儲引擎 存儲引擎特點 特點InnoDBMyISAMMemory存儲限制64TB有有事務安全支持--鎖機制行鎖表鎖表鎖Btree鎖支持支持 支持 Hash索引--支…

編譯 Android gradle-4.6-all.zip 報錯問題記錄

編譯 Android gradle-4.6-all.zip 報錯問題記錄 方法一:替換資源:方法二:修改源方法三:修改版本 編譯時候無法下載 gradle-4.6-all Downloading https://services.gradle.org/distributions/gradle-4.6-all.zip 方法一&#xf…

《一念關山》熱度破萬,愛奇藝古裝賽道出盡風頭

?劉詩詩重回古裝劇、新式武俠公路片、質感細膩的鏡頭美學......看點滿滿的《一念關山》頻頻登上熱搜,俘獲了大批觀眾的心。 開播首日熱度就刷新了愛奇藝2023年站內紀錄,《一念關山》作為2023年愛奇藝在古裝賽道的收官之作,口碑和熱度兼收。…

Linux內核-標準IO和系統IO的區別

概念 標準IO:指的是C語言實現的文件操作的函數 系統IO(文件IO):指的是linux或windows或unix,實現文件操作的函數。 為什么要有兩種IO C語言要實現跨平臺,所以C語言在不同操作系統中實現文件操作方式是不一…

一文詳解Java反射

文章目錄 反射是什么?反射的作用所有方法匯總一、加載Class對象二、加載類的構造器對象三、加載類的成員變量四、加載類的成員方法 反射是什么? 反射就是:加載類,并允許以編程的方式解剖類中的某個成分(成員變量&#…

實戰:Docker Compose 下 Nginx、Java、Mysql 和 Redis 服務協同部署(包含解決瀏覽器訪問Linux部署服務器本地資源問題)

1. 背景 在該實戰中,我們將探討如何使用Docker Compose協同部署Nginx、Java、Mysql和Redis服務,實現一個視頻上傳與展示的應用。具體需求如下: Java應用負責上傳視頻和圖片資源到Nginx目錄下,作為資源服務器。Nginx服務作為靜態…

Numpy數組常用屬性匯總(第5講)

Numpy數組常用屬性匯總 (第5講) ??????? ??博主 侯小啾 感謝您的支持與信賴。?? ????????????????????????????????????????????????????????????????????????????????????…

【JavaEE進階】 Spring使用注解存儲對象

文章目錄 🌴序言🍀前置?作:配置掃描路徑🎄添加注解存儲 Bean 對象🌳類注解🚩為什么要這么多類注解🚩注解之間的聯系 🎋?法注解 Bean🚩?法注解需要配合類注解使? ?總…

探索AIGC未來:CPU源碼優化、多GPU編程與中國算力瓶頸與發展

★人工智能;大數據技術;AIGC;Turbo;DALLE 3;多模態大模型;MLLM;LLM;Agent;Llama2;國產GPU芯片;GPU;CPU;高性能計算機;邊緣計算;大模型顯存占用;5G…

如何夸張孩子

你剛才很努力啊!——表揚努力盡管艱難,但你一直沒有放棄——表揚耐心和堅持你做事情的態度非常不錯——表揚態度你在_____上進步了很多!——表揚細節這個方法真有新意!——表揚創意你和小伙伴合作得真棒!——表揚合作精…

中國特供閹割版 RTX 4090 曝光,老黃這操作絕了

到了現在大伙兒應該發現:國內禁售 NVIDIA RTX 4090 顯卡這事兒基本實錘了。 實際上根據老美規定,從上個月 17 號開始,凡是公司主體在中國的顯卡品牌,就已經不能生產和銷售 RTX 4090。 以后廠商想要賣 4090 只能以整機形式出售&am…

藝術畫廊展廳網站制作的效果如何

藝術展廳往往有很多人前往,在主要城市有不少畫廊,對經營者來說,不同于銷售行業,其更多的是打造品牌吸引用戶前來或合作等形式,而由于行業特殊性,需要準屬性用戶才會前往。 因此在品牌打造及信息承載宣傳方…

防止企業敏感數據泄露

敏感數據泄露是指意外或故意泄露關鍵信息,例如個人身份信息(PII)、支付卡信息(PCI)、受保護的電子健康信息(ePHI)和知識產權(IP),數據保護措施不足的組織會在…

10-Hadoop組件開發技術

單選題 題目1:下列選項描述錯誤的是? 選項: A Hadoop HA即集群中包含Secondary NameNode作為備份節點存在。 B ResourceManager負責的是整個Yarn集群資源的監控、分配和管理工作 C NodeManager負責定時的向ResourceManager匯報所在節點的資源使用情況…

Spark---DataFrame存儲、Spark UDF函數、UDAF函數

四、DataFrame存儲Spark UDF函數 1、儲存DataFrame 1)、將DataFrame存儲為parquet文件 2)、將DataFrame存儲到JDBC數據庫 3)、將DataFrame存儲到Hive表 2、UDF:用戶自定義函數 可以自定義類實現UDFX接口 java: …

案例062:基于微信小程序的健身房私教預約系統

文末獲取源碼 開發語言:Java 框架:SSM JDK版本:JDK1.8 數據庫:mysql 5.7 開發軟件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序開發軟件:HBuilder X 小程序…

模塊式雨水調蓄池施工簡單,無需大型機械,可實現當天開挖當天回填

模塊式雨水調蓄池的施工過程非常簡單,無需大型機械和繁瑣的施工工藝。在施工過程中,只需要進行簡單的開挖和回填即可,而且可以在當天完成。這種施工方式不僅節省了施工時間和成本,還可以避免因大型機械和繁瑣工藝引起的安全隱患。…

MIT_線性代數筆記: 復習一

目錄 問題一問題二問題三問題四 本講為考前復習課,考試范圍就是 Axb 這個單元,重點是長方形矩陣,與此相關的概念包括零空間、左零空間、秩、向量空間、子空間,特別是四個基本子空間。當矩陣為可逆的方陣時,很多性質是一…

二叉樹的層次遍歷

102. 二叉樹的層序遍歷 - 力扣(LeetCode) 題目描述 給你二叉樹的根節點 root ,返回其節點值的 層序遍歷 。 (即逐層地,從左到右訪問所有節點)。 樣例輸入 示例 1: 輸入:root [3…

php研究課題

對于PHP這門語言而言,可以研究的課題有很多,以下是可能的課題方向和對應的內容: PHP語言基礎研究 PHP語言特性和基本語法PHP的數據類型、變量、運算符和表達式PHP的流程控制語句PHP的函數和引用PHP的面向對象編程和設計模式 PHP與Web開發 …