说到队列的话,大家一定不会陌生,但是扯到优先级队列的话,还是有一部分同学是不清楚的,可能是不知道怎么去实现吧,其实呢,,,这东西已

经烂大街了。。。很简单,用“堆”去实现的,在我们系统中有一个订单催付的场景,我们客户的客户在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", );
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 = ;
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 = ; i < ; 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", ); for (int i = ; i < ; 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 = ; 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();
}
}
}
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}

一切都是这么的完美,接下来为了进行可视化验证,你可以在WebUI中观察观察,可以发现在Queue上面多了一个 Pri 标记,有意思吧。

好了,这么重要的功能,是不是已经让你足够兴奋啦, 希望大家能够好好的在实际场景中运用吧~~~

体验Rabbitmq强大的【优先级队列】之轻松面对现实业务场景的更多相关文章

  1. 如何基于RabbitMQ实现优先级队列

    概述 由于种种原因,RabbitMQ到目前为止,官方还没有实现优先级队列,只实现了Consumer的优先级处理. 但是,迫于种种原因,应用层面上又需要优先级队列,因此需求来了:如何为RabbitMQ加 ...

  2. C# RabbitMQ优先级队列实战项目演练

    一.需求背景 当用户在商城上进行下单支付,针对客户等级的不同和订单金额的大小划分客户级别,需要优先处理给标识为大订单的客户发送一份订单邮件提醒.那么我们应用程序如何解决这样的需求场景呢?今天阿笨给大家 ...

  3. RabbitMQ 优先级队列-为队列赋权

    RabbitMQ 消息收发是按顺序收发,一般情况下是先收到的消息先处理,即可以实现先进先出的消息处理.但如果消息者宕机或其他原因,导致消息接收以后,未确认,那么消息会重新Requeue到队列中,就打破 ...

  4. 映射Map、队列Queue、优先级队列PriorityQueue

    映射Map 将对象映射到其他对象的能力是解决编程问题的有效方法.例如,考虑一个程序,它被用来检查 Java 的 Random 类的随机性.理想情况下, Random 会产生完美的数字分布,但为了测试这 ...

  5. RabbitMq学习3-工作队列(Work queues)

    工作队列(又称:任务队列——Task Queues)是为了避免等待一些占用大量资源.时间的操作.当我们把任务(Task)当作消息发送到队列中,一个运行在后台的工作者(worker)进程就会取出任务然后 ...

  6. 源码解析C#中PriorityQueue(优先级队列)的实现

    前言 前段时间看到有大佬对.net 6.0新出的PriorityQueue(优先级队列)数据结构做了解析,但是没有源码分析,所以本着探究源码的心态,看了看并分享出来.它不像普通队列先进先出(FIFO) ...

  7. RabbitMQ使用 prefetch_count优化队列的消费,使用死信队列和延迟队列实现消息的定时重试,golang版本

    RabbitMQ 的优化 channel prefetch Count 死信队列 什么是死信队列 使用场景 代码实现 延迟队列 什么是延迟队列 使用场景 实现延迟队列的方式 Queue TTL Mes ...

  8. Java中的队列Queue,优先级队列PriorityQueue

    队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...

  9. ACM/ICPC 之 优先级队列+设置IO缓存区(TSH OJ-Schedule(任务调度))

    一个裸的优先级队列(最大堆)题,但也有其他普通队列的做法.这道题我做了两天,结果发现是输入输出太过频繁,一直只能A掉55%的数据,其他都是TLE,如果将输入输出的数据放入缓存区,然后满区输出,可以将I ...

随机推荐

  1. Chrome 控制台不完全指南

    Chrome的开发者工具已经强大到没朋友的地步了,特别是其功能丰富界面友好的console,使用得当可以有如下功效: 更高「逼格」更快「开发调试」更强「进阶级的Frontender」 Bug无处遁形「 ...

  2. ABP源码分析四十四:ZERO的配置

    ABP Zero模块中需要配置的地方主要集中在三块:配置静态的role,配置外部认证源,以及配置本地化语言和资源. UserManagementConfig/IUserManagementConfig ...

  3. 对jquery操作复选框

    摘要:jquery操作复选框.使用更简洁易懂,思路清晰,逻辑更明了,很实用 <!DOCTYPE html> <html> <head> <meta chars ...

  4. ReactJs 报错 Element type is invalid: expected a string (from built-in components) or a class/function (for composite components) but got: undefined. Check the render method of `Me`.

    今天在重构一个页面的时候,碰到了一个error,具体的error信息如下图中所示: 最后经过一番查找定位,终于找到了问题所在,原因就是在父组件引用子组件时多加了一个大括号. import {Chart ...

  5. 解析大型.NET ERP系统 自动更新

    C/S架构的应用程序需要支持自动更新功能,当新版本程序发布后,正在运行的客户端能检测到新版本的程序,通知用户是否下载更新.工作以来参与过几个自动更新模块的设计与维护,撰文总结自动更新模块设计与实现. ...

  6. Golang 生成随机数

    package main import ( "fmt" "math/rand" "time" ) func main() { rand.Se ...

  7. 翻唱曲练习:龙珠改主题曲 【Dragon Soul】龙之魂

    首先这是个人翻唱曲: 这个是原版(燃): 伴奏:  翻唱合成为动漫AMV 出镜翻唱: 全民K歌链接: http://kg.qq.com/node/play?s=aYpbMWb6UwoU&g_f ...

  8. Android立体旋转动画实现与封装(支持以X、Y、Z三个轴为轴心旋转)

    本文主要介绍Android立体旋转动画,或者3D旋转,下图是我自己实现的一个界面 立体旋转分为以下三种: 1. 以X轴为轴心旋转 2. 以Y轴为轴心旋转 3. 以Z轴为轴心旋转--这种等价于andro ...

  9. Event Sourcing Pattern 事件源模式

    Use an append-only store to record the full series of events that describe actions taken on data in ...

  10. php内核分析(四)-do_cli

    这里阅读的php版本为PHP-7.1.0 RC3,阅读代码的平台为linux # main 把剩下的代码增加了下注释全部贴出来了(这个是简化后的main函数,去掉了一些无关紧要的代码段): int m ...