RabbitMQ入門教程——路由(Routing)

来源:http://www.cnblogs.com/AlvinLee/archive/2016/12/12/6164733.html
-Advertisement-
Play Games

綁定(Bindings) 之前的文章中我們已經創建過bindings,代碼如下: channel.QueueBind(queue: queueName, exchange: EXCHANGE_NAME, routingKey: ROUTING_KEY, arguments: null); 綁定(bi... ...


綁定( Bindings)

 

之前的文章中我們已經創建過bindings,代碼如下:

 

      channel.QueueBind(queue: queueName, exchange: EXCHANGE_NAME, routingKey: ROUTING_KEY, arguments: null);

 

綁定(bindings)是指交換機(exchange)與隊列(queue)之間的關係。可以簡單的理解為:隊列(queue)對所綁定的交換機(exchange)上的消息感興趣,交換機(exchange)要把它接收到的消息推送到隊列(queue)中。

綁定的時候需要帶上一個額外的參數routingKey,為避免與BasicPublish中的路由鍵(routing key)參數混淆,我們稱之為綁定鍵(binding key),以下是如何創建一個綁定。

 

    channel.QueueBind(queue: queue, exchange: EXCHANGE_NAME, routingKey: "error", arguments: null);

 

註意:

 

直連交換機(direct exchange)

 

在之前的發佈訂閱中我們已經講到直連交換機,我們瞭解到直連交換機的工作方式為——交換機(exchange)會對綁定鍵(binding key)與 路由鍵(routing key)進行精確匹配,然後將消息發送到能夠匹配成功的隊列中。

下圖能夠很好的描述整個場景:

在這個場景中,可以看出直連交換機X和隊列(Q1與Q2)進行了綁定。Q1隊列使用orange為綁定鍵(binding key),Q2有兩個綁定,分別以black和green作為綁定鍵(binding key)。

這樣以來,當路由鍵為orange的消息發送到交換機,就會被路由到隊列Q1,路由鍵為black和green的下拍戲就會被路由到Q2,其它的消息將會被丟棄。

 

多重綁定(multiple bindings)

 

多重綁定即使用一個綁定鍵(binding key)綁定到多個隊列,這是完全合法的,而且每個隊列都能得到完全相同的信息。

 

示例

接下來我們就使用direct exchange完善之前的日誌功能

1.日誌級別為error的日誌保存的到txt文件中

2.日誌級別為log的日誌輸出到控制臺面板

3.輸出所有的日誌到控制臺面板

 

生產者 RoutingProducer.cs

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using RabbitMQ.Client;

using System.Threading;

 

namespace RabbitMQProducer

{

    public class RoutingProducer

    {

        const string EXCHANGE_NAME = "ROUTING_EXCHANGE";

        static readonly List<string> LEVELS = new List<string>() { "error", "log" };

        public static void Send()

        {

 

            ConnectionFactory factory = new ConnectionFactory() { HostName = "localhost" };

            using (IConnection connection = factory.CreateConnection())

            {

                using (IModel channel = connection.CreateModel())

                {

 

                    //創建交換機類型為 direct 的交換機

                    channel.ExchangeDeclare(exchange: EXCHANGE_NAME, type: ExchangeType.Direct);

                    for (int i = 0; i < 20; i++)

                    {

                        Thread.Sleep(100);

                        string level = GetLevels();

                        string message = $"日誌信息:{i}——日誌等級:{level}";

 

                        //發送消息至之前創建的交換機,並設置路由鍵為 日誌級別

                        channel.BasicPublish(exchange: EXCHANGE_NAME, routingKey: level, basicProperties: null, body: Encoding.UTF8.GetBytes(message));

                        Console.WriteLine(message);

                    }

 

                    Console.WriteLine(" Press [enter] to exit.");

                    Console.ReadLine();

                }

            }

        }

 

        private static string GetLevels()

        {

            return LEVELS[new Random().Next(0, 2)];

        }

    }

}

 

消費者 RoutingConsumer.cs

 

using RabbitMQ.Client;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using RabbitMQ.Client.Events;

using System.IO;

namespace RabbitMQConsumer

{

    public class RoutingConsumer

    {

        const string EXCHANGE_NAME = "ROUTING_EXCHANGE";

        /// <summary>

        /// 是否使用多重綁定將所有日誌級別消息輸出到控制台

        /// 預設只是輸出日誌級別為log的內容到控制台

        /// </summary>

        /// <param name="all"></param>

        public static void Log(bool all = false)

        {

            var factory = new ConnectionFactory()

            {

                HostName = "127.0.0.1"

            };

            using (var connection = factory.CreateConnection())

            {

                using (var channel = connection.CreateModel())

                {

                    channel.ExchangeDeclare(exchange: EXCHANGE_NAME, type: ExchangeType.Direct);

                    //每次運行consumer客戶端都創建一個新的queue,並且綁定到對應的exchange,這樣使每次發送消息到exchange時就能把消息由exchange傳遞到所綁定的queue

                    QueueDeclareOk queue = channel.QueueDeclare();

                    string queueName = queue.QueueName;

                    channel.QueueBind(queue: queueName, exchange: EXCHANGE_NAME, routingKey: "log", arguments: null);

                    if (all)

                    {

                        channel.QueueBind(queue: queueName, exchange: EXCHANGE_NAME, routingKey: "error", arguments: null);

                    }

                    EventingBasicConsumer consumer = new EventingBasicConsumer(channel);

                    consumer.Received += (sender, e) =>

                    {

                        string message = Encoding.UTF8.GetString(e.Body);

                        Console.WriteLine($"LOG——日誌信息:{message}");

                    };

                    channel.BasicConsume(queueName, noAck: true, consumer: consumer);

                    Console.WriteLine(" Press [enter] to exit.");

                    Console.ReadLine();

                }

            }

        }

        public static void Error()

        {

            var factory = new ConnectionFactory() { HostName = "127.0.0.1" };

            using (IConnection connection = factory.CreateConnection())

            {

                using (IModel channel = connection.CreateModel())

                {

                    //創建交換機類型為 direct 的交換機

                    channel.ExchangeDeclare(exchange: EXCHANGE_NAME, type: ExchangeType.Direct);

                    //創建一個未命名的新的消息隊列,該隊列名稱有系統自動分配,並且為非持久化,在該隊列沒有訂閱時自動刪除的排它隊列

                    QueueDeclareOk queue = channel.QueueDeclare();

                    string queueName = queue.QueueName;

                    //綁定exchange 與 queue 並設置路由鍵為日誌級別error

                    channel.QueueBind(queue: queue, exchange: EXCHANGE_NAME, routingKey: "error", arguments: null);

                    EventingBasicConsumer consumer = new EventingBasicConsumer(channel);

                    consumer.Received += (sender, arg) =>

                    {

                        string message = Encoding.UTF8.GetString(arg.Body);

                        //寫入日誌到txt文件

                        using (StreamWriter writer = new StreamWriter(@"c:\log\log.txt", true, Encoding.UTF8))

                        {

                            writer.WriteLine(message);

                            writer.Close();

                        }

                    };

                    channel.BasicConsume(queue: queueName, noAck: true, consumer: consumer);

                }

            }

        }

    }

}


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

-Advertisement-
Play Games
更多相關文章
  • 今天做一個管理後臺菜單,想著要用無限極分類,記得園子里還是什麼地方見過這種寫法,可今天找了半天也沒找到,沒辦法靜下心來自己寫了: 首先創建節點類(我給它取名:AdminUserTree): 為無限極分類填充數據,由於考慮到示來管理後臺每個頁面都會調用到,這裡我為控制器創建了一個基類方法 控制器(Co ...
  • 如今的軟體市場,競爭已經進入白熱化階段,功能強、運算快、界面友好、Bug少、價格低都已經成為了必備條件。這還不算完,隨著電腦的多媒體功能越來越強,軟體的界面是否色彩亮麗、是否能通過動畫、3D等效果是否吸引用戶的眼球也已經成為衡量軟體的標準。 軟體項目成功的三個要素是:資源、成本、時間。無論是為了在 ...
  • 最近悟出來一個道理,在這兒分享給大家:學歷代表你的過去,能力代表你的現在,學習代表你的將來。 十年河東十年河西,莫欺少年窮 學無止境,精益求精 本節探討C#獲取漢字拼音首字母的方法: 代碼類東西,直接上代碼: 截取字元串的方法: 以上便是完整代碼,謝謝! 在此,順便說下資料庫按照漢字首字母進行排序的 ...
  • using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace test4 { class Program { ... ...
  • 上一章節講解如何新建WCF服務,此文講解如何在IIS上發佈,並能正常訪問 首先在本機安裝IIS,IIS如何勾選,哪些是必須的?不太清楚,有清楚的大牛請指正!目前我的基本配置如下: 首先在本機安裝IIS,IIS如何勾選,哪些是必須的?不太清楚,有清楚的大牛請指正!目前我的基本配置如下: 配置完成後,重 ...
  • 其中 這個 Property 設置的是當有焦點時顯示的樣式,Value 設置為 x:Null 代表不會有任何改變,當然你也可以自己寫一個。 應用 引用: https://msdn.microsoft.com/zh-cn/library/ms753328(v=vs.110).aspx ...
  • CORS原理: 向響應頭header中註入Access-Control-Allow-Origin,這樣瀏覽器檢測到header中的Access-Control-Allow-Origin,則就可以跨域操作了。 句代碼中*代碼,伺服器允許任何人訪問。也可以設置規定訪問的功能變數名稱。比如只允許http://xx ...
  • 目錄: 什麼是Razor? 渲染HTML Razor語法 隱式 Razor 表達式 顯式 Razor 表達式 什麼是Razor? Razor是基於服務端代碼轉換成網頁的標記語法。語法主要包括Razor標記、C#和HTML組成。包含Razor語法的主要文件是.cshtml。 渲染HTML Razor的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...