體驗Rabbitmq強大的【優先順序隊列】之輕鬆面對現實業務場景

来源:http://www.cnblogs.com/huangxincheng/archive/2016/11/04/6029214.html
-Advertisement-
Play Games

說到隊列的話,大家一定不會陌生,但是扯到優先順序隊列的話,還是有一部分同學是不清楚的,可能是不知道怎麼去實現吧,其實呢,,,這東西已 經爛大街了。。。很簡單,用“堆”去實現的,在我們系統中有一個訂單催付的場景,我們客戶的客戶在tmall,taobao下的訂單,taobao會及時將訂單推送給 我們,如果 ...


         說到隊列的話,大家一定不會陌生,但是扯到優先順序隊列的話,還是有一部分同學是不清楚的,可能是不知道怎麼去實現吧,其實呢,,,這東西已

經爛大街了。。。很簡單,用“堆”去實現的,在我們系統中有一個訂單催付的場景,我們客戶的客戶在tmall,taobao下的訂單,taobao會及時將訂單推送給

我們,如果在用戶設定的時間內未付款那麼就會給用戶推送一條簡訊提醒,很簡單的一個功能對吧,但是,tmall商家對我們來說,肯定是要分大客戶和小客

戶的對吧,比如像施華蔻,百雀林這樣大商家一年起碼能夠給我們貢獻幾百萬,所以理應當然,他們的訂單必須得到優先處理,而曾今我們的後端系統是使

用redis來存放的定時輪詢,大家都知道redis只能用List做一個簡簡單單的消息隊列,並不能實現一個優先順序的場景,所以訂單量大了後採用rabbitmq進行

改造和優化,如果發現是大客戶的訂單給一個相對比較高的優先順序,否則就是預設優先順序,好了,廢話不多說,我們來看看如何去設置。

 

一:優先順序隊列

  既然是優先順序隊列,那麼必然要在Queue上開一個口子貼上一個優先順序的標簽,為了看怎麼設置,我們用一下rabbitmq的監控UI,看看這個裡面是如何

手工的創建優先順序隊列。

      從這個圖中可以看到在Arguments欄中有特別多的小屬性,其中有一項就是"Maximum priority",這項的意思就是說可以定義優先順序的最大值,其實

想想也是,不可能我們定義的優先順序是一個非常大的數字,比如int.MaxValue,大多情況下都是10以內的數字就可以了,再或者我們曾今接觸過的 MSMQ,

它的優先順序只是一些枚舉值,什麼High,Normal,Low,不知道大家可否記得? 下麵來看下代碼中該如何實現呢???

 

1. 在Queue上附加優先順序屬性

Dictionary<string, object> dic = new Dictionary<string, object>();
dic.Add("x-max-priority", 20);
channel.QueueDeclare(queue: "hello",
                                durable: true,
                                exclusive: false,
                                autoDelete: false,
                                arguments: dic);

 

 上面的代碼做了一個簡單的隊列聲明,queuename="hello",持久化,排外。。。然後把"x-max-priority"塞入到字典中作為arguments參數,看起來還

是非常簡單吧~~~

 

2. 在Message上指定優先順序屬性

 var properties = channel.CreateBasicProperties();
 properties.Priority = 1;
 channel.BasicPublish(exchange: "",
                      routingKey: "hello",
                      basicProperties: null,
                      body: body);

 

通過上面的代碼可以看到,在Message上設置優先順序,我是通過在channel通道上設置Priority屬性,之後塞到basicProperties中就可以了,好了,有上面這兩

個基礎之後,下麵就可以開始測試了,準備向rabbitmq推送10條記錄,其中第5條的優先順序最高,所以應該首先就print出來,如下圖:

static void Main(string[] args)
{
    var sb = new StringBuilder();

    for (int i = 0; i < 11; i++)
    {
        sb.Append(i);
    }

    var factory = new ConnectionFactory() { HostName = "192.168.23.136", UserName = "datamip", Password = "datamip" };

    using (var connection = factory.CreateConnection())
    {
        using (var channel = connection.CreateModel())
        {
            channel.ExchangeDeclare(exchange: "mydirect", type: ExchangeType.Direct, durable: true);

            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("x-max-priority", 20);

            for (int i = 0; i < 10; i++)
            {
                channel.QueueDeclare(queue: "hello",
                                            durable: true,
                                            exclusive: false,
                                            autoDelete: false,
                                            arguments: dic);

                string message = string.Format("{0} {1}", i, sb.ToString());
                var body = Encoding.UTF8.GetBytes(message);

                var properties = channel.CreateBasicProperties();

                properties.Priority = (i == 5) ? (byte)10 : (byte)i;

                channel.BasicPublish(exchange: "",
                                     routingKey: "hello",
                                     basicProperties: properties,
                                     body: body);

                Console.WriteLine(" [x] Sent {0}", i);
            }
        }
    }

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

 

圖中可以看到10條消息我都送到rabbitmq中去了,接下來打開consume端,來看看所謂的index=5 是否第一個送出來??

static void Main(string[] args)
{
    for (int m = 0; m < int.MaxValue; m++)
    {
        var factory = new ConnectionFactory() { HostName = "192.168.23.136", UserName = "datamip", Password = "datamip" };

        using (var connection = factory.CreateConnection())
        using (var channel = connection.CreateModel())
        {
            var result = channel.BasicGet("hello", true);

            if (result != null)
            {
                var str = Encoding.UTF8.GetString(result.Body);
                Console.WriteLine("{0}  消息內容 {1}", m, str);
                System.Threading.Thread.Sleep(1);
            }
        }
    }
    Console.WriteLine(" Press [enter] to exit.");
    Console.ReadLine();
}

 

一切都是這麼的完美,接下來為了進行可視化驗證,你可以在WebUI中觀察觀察,可以發現在Queue上面多了一個 Pri 標記,有意思吧。

 

 

好了,這麼重要的功能,是不是已經讓你足夠興奮啦, 希望大家能夠好好的在實際場景中運用吧~~~

 


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

-Advertisement-
Play Games
更多相關文章
  • sql server 2012深入解析與性能優化(第3版) 第五章 查詢處理和執行 1.sqlserver通過四個步驟處理一個查詢,分析,algebrizing,優化,執行。2.分析是分析語法錯誤生成分析樹,綁定部分有,名字解析,類型推倒,聚合綁定,組合綁定。查詢優化器,將查詢樹找到好的執行計劃,如 ...
  • 最近學習了一下SQL的分頁查詢,總結了以下幾種方法。 首先建立了一個表,隨意插入的一些測試數據,表結構和數據如下圖: 現在假設我們要做的是每頁5條數據,而現在我們要取第三頁的數據。(數據太少,就每頁5條了) 方法一: 結果: 此方法是先取出前10條的SID(前兩頁),排除前10條數據的SID,然後在 ...
  • 介紹 LIST分區和RANGE分區非常的相似,主要區別在於LIST是枚舉值列表的集合,RANGE是連續的區間值的集合。二者在語法方面非常的相似。同樣建議LIST分區列是非null列,否則插入null值如果枚舉列表裡面不存在null值會插入失敗,這點和其它的分區不一樣,RANGE分區會將其作為最小分區 ...
  • 標簽: MongoDB NoSQL MongoDB 存儲引擎和數據模型設計 1. 存儲引擎 1.1 存儲引擎是什麼 1.2 MongoDB中的預設存儲引擎 2. 數據模型設計 2.1 內嵌和引用 2.2 設計原則 A. 1 1 或者 1 (較少) B. 1 (較多) C. 1 (非常多) D. E. ...
  • 1. 概述 最近在ESB項目中,客戶在各個系統之間的服務調用大多都是在oracle存儲過程中進行的,本文就oracle存儲過程調用web service來進行說明。其他主流資料庫,比如mysql和sql service,調用web service的方法這裡就不做介紹了,本文主要用來介紹oracle存 ...
  • 今天在將CSV導入到oracle時,報了下麵的異常: SQL*Loader-522: lfiopn failed for file 後來從MSDN找到了原因,文件夾的許可權不夠。 環境描述:我的導入文件放在WIN7系統桌面上的,該導入文件是從桌面上另外一個成功導入的例子 複製的 。 處理方案:複製到的 ...
  • 使用ES的基本都會使用過head,但是版本升級到5.0後,head插件就不好使了。下麵就看看如何在5.0中啟動Head插件吧! "官方粗略教程" Running with built in server enable cors by adding http.cors.enabled: true in ...
  • 介紹 COLUMN分區是5.5開始引入的分區功能,只有RANGE COLUMN和LIST COLUMN這兩種分區;支持整形、日期、字元串;RANGE和LIST的分區方式非常的相似。 COLUMNS和RANGE和LIST分區的區別 1.針對日期欄位的分區就不需要再使用函數進行轉換了,例如針對date字 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...