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

经烂大街了。。。很简单,用“堆”去实现的,在我们系统中有一个订单催付的场景,我们客户的客户在tmall,taobao下的订单,taobao会及时将订单推送给

我们,如果在用户设定的时间内未付款那么就会给用户推送一条短信提醒,很简单的一个功能对吧,但是,tmall商家对我们来说,肯定是要分大客户和小客

户的对吧,比如像施华蔻,百雀林这样大商家一年起码能够给我们贡献几百万,所以理应当然,他们的订单必须得到优先处理,而曾今我们的后端系统是使

用redis来存放的定时轮询,大家都知道redis只能用List做一个简简单单的消息队列,并不能实现一个优先级的场景,所以订单量大了后采用rabbitmq进行

改造和优化,如果发现是大客户的订单给一个相对比较高的优先级,否则就是默认优先级,好了,废话不多说,我们来看看如何去设置。

一:优先级队列

  既然是优先级队列,那么必然要在Queue上开一个口子贴上一个优先级的标签,为了看怎么设置,我们用一下rabbitmq的监控UI,看看这个里面是如何

手工的创建优先级队列。

从这个图中可以看到在Arguments栏中有特别多的小属性,其中有一项就是"Maximum priority",这项的意思就是说可以定义优先级的最大值,其实

想想也是,不可能我们定义的优先级是一个非常大的数字,比如int.MaxValue,大多情况下都是10以内的数字就可以了,再或者我们曾今接触过的 MSMQ,

它的优先级只是一些枚举值,什么High,Normal,Low,不知道大家可否记得? 下面来看下代码中该如何实现呢???

1. 在Queue上附加优先级属性

  1. Dictionary<string, object> dic = new Dictionary<string, object>();
  2. dic.Add("x-max-priority", );
  3. channel.QueueDeclare(queue: "hello",
  4. durable: true,
  5. exclusive: false,
  6. autoDelete: false,
  7. arguments: dic);

上面的代码做了一个简单的队列声明,queuename="hello",持久化,排外。。。然后把"x-max-priority"塞入到字典中作为arguments参数,看起来还

是非常简单吧~~~

2. 在Message上指定优先级属性

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

通过上面的代码可以看到,在Message上设置优先级,我是通过在channel通道上设置Priority属性,之后塞到basicProperties中就可以了,好了,有上面这两

个基础之后,下面就可以开始测试了,准备向rabbitmq推送10条记录,其中第5条的优先级最高,所以应该首先就print出来,如下图:

  1. static void Main(string[] args)
  2. {
  3. var sb = new StringBuilder();
  4.  
  5. for (int i = ; i < ; i++)
  6. {
  7. sb.Append(i);
  8. }
  9.  
  10. var factory = new ConnectionFactory() { HostName = "192.168.23.136", UserName = "datamip", Password = "datamip" };
  11.  
  12. using (var connection = factory.CreateConnection())
  13. {
  14. using (var channel = connection.CreateModel())
  15. {
  16. channel.ExchangeDeclare(exchange: "mydirect", type: ExchangeType.Direct, durable: true);
  17.  
  18. Dictionary<string, object> dic = new Dictionary<string, object>();
  19. dic.Add("x-max-priority", );
  20.  
  21. for (int i = ; i < ; i++)
  22. {
  23. channel.QueueDeclare(queue: "hello",
  24. durable: true,
  25. exclusive: false,
  26. autoDelete: false,
  27. arguments: dic);
  28.  
  29. string message = string.Format("{0} {1}", i, sb.ToString());
  30. var body = Encoding.UTF8.GetBytes(message);
  31.  
  32. var properties = channel.CreateBasicProperties();
  33.  
  34. properties.Priority = (i == 5) ? (byte)10 : (byte)i;
  35.  
  36. channel.BasicPublish(exchange: "",
  37. routingKey: "hello",
  38. basicProperties: properties,
  39. body: body);
  40.  
  41. Console.WriteLine(" [x] Sent {0}", i);
  42. }
  43. }
  44. }
  45.  
  46. Console.WriteLine(" Press [enter] to exit.");
  47. Console.ReadLine();
  48. }

图中可以看到10条消息我都送到rabbitmq中去了,接下来打开consume端,来看看所谓的index=5 是否第一个送出来??

  1. static void Main(string[] args)
  2. {
  3. for (int m = ; m < int.MaxValue; m++)
  4. {
  5. var factory = new ConnectionFactory() { HostName = "192.168.23.136", UserName = "datamip", Password = "datamip" };
  6.  
  7. using (var connection = factory.CreateConnection())
  8. using (var channel = connection.CreateModel())
  9. {
  10. var result = channel.BasicGet("hello", true);
  11.  
  12. if (result != null)
  13. {
  14. var str = Encoding.UTF8.GetString(result.Body);
  15. Console.WriteLine("{0} 消息内容 {1}", m, str);
  16. System.Threading.Thread.Sleep();
  17. }
  18. }
  19. }
  20. Console.WriteLine(" Press [enter] to exit.");
  21. Console.ReadLine();
  22. }

一切都是这么的完美,接下来为了进行可视化验证,你可以在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. 构建Web API服务

    返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 构建动态Web API控制器 ABP可以自动地为应用层生成Web API 层.比如说我们之前创建的应用层: namespace N ...

  2. GIT服务器的四种协议

    本地协议 最基本的就是_本地协议(Local protocol)_,所谓的远程仓库在该协议中的表示,就是硬盘上的另一个目录.这常见于团队每一个成员都对一个共享的文件系统(例如 NFS)拥有访问权,或者 ...

  3. javaEE设计模式——门面模式

    1.本节内容 门面模式的意图介绍 门面模式带来的好处 门面模式的应用场景 实现模式的3中方式:POJO.无状态与有状态回话Bean门面 有状态与无状态回话Bean门面的重要差别 关于门面模式使用的警告 ...

  4. Java环境变量-Linux环境

    环境变量说明 JAVA_HOME 它指向jdk的安装目录,Eclipse/NetBeans/Tomcat等软件就是通过搜索JAVA_HOME变量来找到并使用安装好的jdk. PATH 作用是指定命令搜 ...

  5. 基於tiny4412的Linux內核移植--- 中斷和GPIO學習(2)

    作者 彭東林 pengdonglin137@163.com 平臺 tiny4412 ADK Linux-4.4.4 u-boot使用的U-Boot 2010.12,是友善自帶的,爲支持設備樹和uIma ...

  6. docker进入后台运行的容器

    转载请注明出处   我们运行docker容器的时候,使用了-d参数,把容器在后台运行后. 这个时候,我们使用docker ps命令,我们就可以知道哪些程序在后台运行.   我们要怎么进入到docker ...

  7. CentOS7使用firewalld打开关闭防火墙与端口

    1.firewalld的基本使用 启动: systemctl start firewalld 查看状态: systemctl status firewalld  停止: systemctl disab ...

  8. 设置nginx禁止IP直接访问,只能通过指定的域名访问

    nginx的版本是1.2.1. 设置配置文件disableip.conf: server {     listen 80;     server_name _;     return500; } 这是 ...

  9. MongoDB初识

    参考: MongoDB资料汇总专题:

  10. FastSocket学习笔记~再说客户端与服务端的组成

    废话多说 很久之前,我写过几篇FastSocket的文章,基本属于使用的方法,而缺乏对概念的总结讲解,而本讲就是弥补一下上几讲的不足,将核心的模块再说说,再谈谈,再聊聊! 首先FastSocket由C ...