C#隊列學習筆記:RabbitMQ基礎知識

来源:https://www.cnblogs.com/atomy/archive/2020/03/29/12581619.html
-Advertisement-
Play Games

一、引言 RabbitMQ是Rabbit Message Queue的簡寫,但不能僅僅理解其為消息隊列,消息代理更合適。RabbitMQ是一個由 Erlang 語言開發的AMQP(高級消息隊列協議)的開源實現,其內部結構如下: RabbitMQ作為一個消息代理,主要和消息打交道,負責接收並轉發消息。 ...


    一、引言

    RabbitMQ是Rabbit Message Queue的簡寫,但不能僅僅理解其為消息隊列,消息代理更合適。RabbitMQ是一個由 Erlang 語言開發的AMQP(高級消息隊列協議)的開源實現,其內部結構如下:

RabbitMQ 內部結構

    RabbitMQ作為一個消息代理,主要和消息打交道,負責接收並轉發消息。RabbitMQ提供了可靠的消息機制、跟蹤機制和靈活的消息路由,支持消息集群和分散式部署。適用於排隊演算法、秒殺活動、消息分發、非同步處理、數據同步、處理耗時任務、CQRS等應用場景。

    二、基礎概念

     講解基礎概念之前,先來構造一個整體結構圖,以方便我們更好地去理解RabbitMQ的基本原理。

    通過上面這張結構圖,能夠清晰地瞭解到Send Message到Receive Message的一個大致流程。

    2.1、Queue

    Queue(隊列)在RabbitMQ中的作用是存儲消息,隊列的特性是先進先出。上圖可以清晰地看到Client A和Client B是生產者,生產者生產消息最終被送到RabbitMQ的內部對象Queue中去,而消費者則是從Queue中取出數據,可以簡化表示為:

    生產者Send Message,“A”被傳送到Queue中,消費者發現消息隊列Queue中有訂閱的消息,就會將這條消息A讀取出來進行一系列的業務操作。這裡是一個消費者對應一個隊列Queue,也可以多個消費者訂閱同一個隊列Queue,此時就會將Queue裡面的消息平分給其他的消費者,但是會存在一個問題就是如果每個消息的處理時間不同,就會導致某些消費者一直在忙碌中,而有的消費者處理完消息後一直處於空閑狀態。這時我們可以使用prefetchCount來限制每次發送給消費者消息的個數,詳情見下圖所示:

    這裡的prefetchCount=1是指每次從Queue中發送一條消息,等消費者處理完這條消息後,Queue會再發送一條消息給消費者。

    2.2、Exchange

    在本節開頭的結構圖中我們留下了一個坑:消費者Client A和消費者Client B,是如何知道要發送的消息是給Queue1還是給Queue2的呢?下麵讓我們來解開這個面紗。首先要明確的一點是:生產者生產的消息並不是直接發送給消息隊列Queue的,而是要經過Exchange(交換器)將消息路由到一個或多個Queue,當然這裡還會對不符合路由規則的消息進行丟棄,這個涉及到後面要講的Exchange Type。那麼Exchange是怎樣將消息準確地推送到對應的Queue的呢?功勞最大的當屬Binding。RabbitMQ通過Binding將Exchange和Queue鏈接在一起,這樣Exchange就知道如何將消息準確地推送到Queue中去了,簡單示意圖如下所示:

    生產者將消息發送給Exchange的時候,一般會產生一個Routing Key,而通過Binding鏈接Exchange和Queue的時候,一般會指定一個Binding Key。當Routing Key與Binding Key對應得上的時候,消息就會發送到對應的Queue中去。

     2.3、Exchange Type

    Exchange Type有4種,不同的類型有著不同的策略,也就意味著類型的不同將決定著綁定的Queue的不同。換言之,生產者發送了一個消息,Routing Key的規則是A,那麼生產者會將Routing Key=A的消息推送到Exchange中,這時候Exchange根據自己的規則去篩選生產者發來的消息。

  • fanout

    fanout類型的Exchange,路由規則非常簡單:它會把所有發送到該Exchange的消息,路由到所有與它綁定的Queue中。

    上圖所示,生產者(P)將消息1推送到Exchange,由於Exchange Type=fanout,這時候會遵循fanout的規則將消息推送到所有與它綁定的Queue中(上圖的兩個Queue),最後給兩個消費者消費。

  • direct

    direct類型的Exchange,路由規則也很簡單:它會把消息路由到那些Routing Key與Binding Key完全匹配的Queue中。

    當生產者(P)發送消息時Rotuing key=booking,Exchange獲取到生產者發送過來的消息後,會根據自身的規則進行匹配相應的Queue,這時發現Queue1和Queue2都符合,就會將消息傳送給這兩個隊列。如果我們以Rotuing key=create和Rotuing key=confirm發送消息時,這時消息只會被推送到Queue2隊列中,其它Routing Key的消息將會被丟棄。

  • topic

    如果說前面的direct規則是嚴格意義上的匹配(即Routing Key必須與Binding Key相匹配的時候才將消息傳送給Queue),那麼topic這個規則就是模糊匹配,可以通過通配符滿足一部分規則就可以傳送,它的約定是:

    1)Routing Key為一個句點號“. ”分隔的字元串(我們將被句點號“. ”分隔開的每一段獨立的字元串稱為一個單詞),如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit”。

    2)Binding Key與Routing Key一樣也是句點號“. ”分隔的字元串。

    3)Binding Key中可以存在兩種特殊字元“*”與“#”,用於做模糊匹配,其中“*”用於匹配一個單詞,“#”用於匹配多個單詞(可以是零個)。

    當生產者發送消息Routing Key=F.C.E的時候,這時候只滿足Queue1,所以會被路由到Queue1中;如果Routing Key=A.C.E這時候會被同時路由到Queue1和Queue2中;如果Routing Key=A.F.B時,這時只會路由到Queue2中。

  • headers

    headers類型的Exchange,不依賴於Routing Key與Binding Key的匹配規則來路由消息,而是根據發送的消息內容中的headers屬性進行匹配。

    在綁定Exchange與Queue時指定一組鍵值對,當消息發送到Exchange時,RabbitMQ會取到該消息的headers(也是一個鍵值對的形式),並對比其中的鍵值對是否完全匹配Exchange與Queue綁定時指定的鍵值對,如果完全匹配則消息會路由到該Queue,否則不會路由到該Queue。該類型的Exchange沒有用到過(不過也應該很有用武之地),所以不作介紹。

    下麵對4種Exchange類型進行簡要的表格整理:

Exchange規則
類型名稱 類型描述
fanout 把所有發送到該Exchange的消息路由到所有與它綁定的Queue中
direct Routing Key==Binding Key
topic 簡稱模糊匹配
headers Exchange不依賴於Routing Key與Binding Key的匹配規則來路由消息,而是根據發送的消息內容中的headers屬性進行匹配。

    2.4、補充說明

    ConnectionFactory、Connection、Channel:都是RabbitMQ對外API中最基本的對象。

    ConnectionFactory:Connection的製造工廠。

    Connection:RabbitMQ的socket鏈接,它封裝了socket協議相關的邏輯。Connection建立一個TCP連接,生產者和消費者通過TCP連接到RabbitMQ Server。

    Channel:

    1)Channel是與RabbitMQ打交道的最重要的一個介面,我們大部分的業務操作都是通過Channel這個介面來完成的,包括定義Exchange與Queue、綁定Exchange與Queue、發佈消息等。

    2)Channel虛擬連接,是建立在上面TCP連接的基礎上。數據流動都是通過Channel來進行的,為什麼不是直接在TCP連接上進行數據流動呢?是因為建立和關閉TCP連接是有代價的。頻繁地建立與關閉TCP連接對於系統的性能有很大的影響,而且TCP的連接數也有限制,這也限制了系統處理高併發的能力,而在TCP連接中建立Channel是沒有上述代價的。

 

    參考自:

    https://www.cnblogs.com/dwlsxj/p/RabbitMQ.html

    https://www.cnblogs.com/sheng-jie/p/7192690.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 發現按照教程操作破解Eplan,破解一直不成功。主要原因是MultiKey64在win10上運行不成功。可以通過設備管理看到是否有下圖的驅動 需要關閉win10的簽名認證,這個鏈接就是關閉的方法https://jingyan.baidu.com/article/624e74594dbc8d34e8b ...
  • 你需要瞭解的 HTTP Status Code Intro 現在前後端分離的開發模式越來越流行,後端負責開發對應的 API,前端只需要 關註前端頁面的數據展示和前端邏輯即可。 對於前後端分離這種開發模式,我個人還是比較喜歡的,因為這樣可以讓更專業的人做更專業的事情,後端專註於做 API 的開發設計, ...
  • 在ASP.NET MVC中有四種過濾器類型 Action 1、在ASP.NET MVC項目中,新建文件夾Filter,然後新建類MyCustormFilter,繼承自ActionFilterAttribute類,我們來看下ActionFilterAttribute類有如下四個方法,從命名我應該就可以 ...
  • 面向對象 面向對象是一個抽象的概念,其本質就是對事物以抽象的方式建立對應的模型。 簡單來講,比如我有一隻鋼筆,那麼我就可以通過分析,可以得到 這隻鋼筆的材第是塑料,品牌是個雜牌 ,裡面裝的墨是黑色的,可以用。這時候就能建立一個鋼筆的模型,它在這裡應該有這些屬性: 圖是一個不正確的UML類圖,但是可以 ...
  • 在上一篇abp(net core)+easyui+efcore實現倉儲管理系統——入庫管理之五(四十一) 文章中實現了入庫管理的列表頁面,並實現了控制器的代碼。在今天我們學習如何在前端實現新增入庫單信息界面。 ...
  • 在偶然一次調試某程式時,遇到提示: 無法載入程式集*****.XmlSerializers.dll,文件找不到(Could not load file or assembly ****.XmlSerializers.dll , FileNotFoundException...)。於是嘗試在項目屬性中 ...
  • 首先,好消息是Goole將於2020年2月份發佈Chrome 80版本。本次發佈將推進Google的“漸進改良Cookie”策略,打造一個更為安全和保障用戶隱私的網路環境。 壞消息是,本次更新可能導致瀏覽器無法向服務端發送Cookie。如果你有多個不同功能變數名稱的應用,部分用戶很有可能出現會話時常被打斷的 ...
  • TerminalMACS(Terminal Manager And Check System) 遠程終端管理和檢測系統 本文同步更新地址:https://dotnet9.com/11429.html 一、本系統可監控多種終端資源: 移動端 Android iOS PC端 Windows Linux ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...