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

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

一、引言 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


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

更多相關文章
  • 發現按照教程操作破解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 ...
一周排行
  • 一:背景 1. 講故事 如果你常翻看FCL的源碼,你會發現這裡面有不少方法藉助了C/C++的力量讓C#更快更強悍,如下所示: [DllImport("QCall", CharSet = CharSet.Unicode)] [SecurityCritical] [SuppressUnmanagedCo ...
  • 上一篇(https://www.cnblogs.com/meowv/p/12966092.html)文章使用AutoMapper來處理對象與對象之間的映射關係,本篇主要圍繞定時任務和數據抓取相關的知識點並結合實際應用,在定時任務中迴圈處理爬蟲任務抓取數據。 開始之前可以刪掉之前測試用的幾個Hello ...
  • 首先創建實體類 1 public class MacState 2 { 3 /// <summary> 4 /// 請求狀態 5 /// </summary> 6 public string success { get; set; } 7 /// <summary> 8 /// 錯誤信息 9 /// ...
  • 0. 前言 前幾天FreeSql的作者向我推薦了FreeSql框架,想讓我幫忙寫個文章介紹一下。嗯,想不到我也能帶個貨了。哈哈,開個玩笑~看了下覺得設計的挺有意思的,所以就謝了這篇文章。 簡單介紹一下,FreeSql 是NCC組織的沙盒級項目,是一款功能強大的 ORM 組件,支持 .NET Core ...
  • 0. 前言 這是一個新的系列,名字是《ASP.NET Core 入門到實戰》。這個系列主講ASP.NET Core MVC,輔助一些前端的基礎知識(能用來實現我們需要的即可,並非主講)。同時這個系列也會在後續介紹ASP.NET Core 平臺的其它類型的項目,並帶領大家以各個類型的項目為主要架構開發 ...
  • 我寫了一個Winform測試程式,用的System.Timers.Timer,在事件里,設置label1.Text,然後,居然句柄泄漏、用戶對象泄漏! 百思不得其解,最後換成System.Windows.Forms.Timer,居然不泄漏了! 最近睡眠不足,哪怕一個很小的問題,隨便搞搞,都半夜了! ...
  • leetcode-7. 整數反轉。 給出一個 32 位的有符號整數,你需要將這個整數中每位上的數字進行反轉。 示例 1: 輸入: 123 輸出: 321 示例 2: 輸入: -123 輸出: -321 示例 3: 輸入: 120 輸出: 21 註意: 假設環境只能存儲得下 32 位的有符號整數,則其 ...
  • 1. Java 虛擬機是什麼? 1.1 虛擬機 虛擬機:虛擬的電腦,一個用來執行虛擬電腦指令的軟體。 虛擬機分為系統虛擬機和程式虛擬機。 系統虛擬機:提供一個可運行完整操作系統的軟體平臺,如 Visual Box、VMware。 程式虛擬機:專門執行單個程式的,典型代表 Java 虛擬機。Jav ...
  • 前言 - strlen 概述 無意間掃到 glibc strlen.c 中代碼, 久久不能忘懷. 在一無所知的編程生涯中又記起點點滴滴: 編程可不是兒戲 ❀, 有些難, 也有些不捨. 隨軌跡一同重溫, 曾經最熟悉的 strlen 手感吧 ~ /* Copyright (C) 1991-2020 Fr ...
  • 背景 隊列[Queue]:是一種限定僅在表頭進行刪除操作,僅在表尾進行插入操作的線性表;即先進先出(FIFO-first in first out):最先插入的元素最先出來。 本文通過編碼實現鏈式隊列類,並模擬一個有趣的應用,能夠幫助我們對鏈式隊列有更深度的理解。 基本概念 結點 每個元素,除了存儲 ...