体验Rabbitmq强大的【优先级队列】之轻松面对现实业务场景
说到队列的话,大家一定不会陌生,但是扯到优先级队列的话,还是有一部分同学是不清楚的,可能是不知道怎么去实现吧,其实呢,,,这东西已
经烂大街了。。。很简单,用“堆”去实现的,在我们系统中有一个订单催付的场景,我们客户的客户在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强大的【优先级队列】之轻松面对现实业务场景的更多相关文章
- 如何基于RabbitMQ实现优先级队列
概述 由于种种原因,RabbitMQ到目前为止,官方还没有实现优先级队列,只实现了Consumer的优先级处理. 但是,迫于种种原因,应用层面上又需要优先级队列,因此需求来了:如何为RabbitMQ加 ...
- C# RabbitMQ优先级队列实战项目演练
一.需求背景 当用户在商城上进行下单支付,针对客户等级的不同和订单金额的大小划分客户级别,需要优先处理给标识为大订单的客户发送一份订单邮件提醒.那么我们应用程序如何解决这样的需求场景呢?今天阿笨给大家 ...
- RabbitMQ 优先级队列-为队列赋权
RabbitMQ 消息收发是按顺序收发,一般情况下是先收到的消息先处理,即可以实现先进先出的消息处理.但如果消息者宕机或其他原因,导致消息接收以后,未确认,那么消息会重新Requeue到队列中,就打破 ...
- 映射Map、队列Queue、优先级队列PriorityQueue
映射Map 将对象映射到其他对象的能力是解决编程问题的有效方法.例如,考虑一个程序,它被用来检查 Java 的 Random 类的随机性.理想情况下, Random 会产生完美的数字分布,但为了测试这 ...
- RabbitMq学习3-工作队列(Work queues)
工作队列(又称:任务队列——Task Queues)是为了避免等待一些占用大量资源.时间的操作.当我们把任务(Task)当作消息发送到队列中,一个运行在后台的工作者(worker)进程就会取出任务然后 ...
- 源码解析C#中PriorityQueue(优先级队列)的实现
前言 前段时间看到有大佬对.net 6.0新出的PriorityQueue(优先级队列)数据结构做了解析,但是没有源码分析,所以本着探究源码的心态,看了看并分享出来.它不像普通队列先进先出(FIFO) ...
- RabbitMQ使用 prefetch_count优化队列的消费,使用死信队列和延迟队列实现消息的定时重试,golang版本
RabbitMQ 的优化 channel prefetch Count 死信队列 什么是死信队列 使用场景 代码实现 延迟队列 什么是延迟队列 使用场景 实现延迟队列的方式 Queue TTL Mes ...
- Java中的队列Queue,优先级队列PriorityQueue
队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...
- ACM/ICPC 之 优先级队列+设置IO缓存区(TSH OJ-Schedule(任务调度))
一个裸的优先级队列(最大堆)题,但也有其他普通队列的做法.这道题我做了两天,结果发现是输入输出太过频繁,一直只能A掉55%的数据,其他都是TLE,如果将输入输出的数据放入缓存区,然后满区输出,可以将I ...
随机推荐
- 构建Web API服务
返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 构建动态Web API控制器 ABP可以自动地为应用层生成Web API 层.比如说我们之前创建的应用层: namespace N ...
- GIT服务器的四种协议
本地协议 最基本的就是_本地协议(Local protocol)_,所谓的远程仓库在该协议中的表示,就是硬盘上的另一个目录.这常见于团队每一个成员都对一个共享的文件系统(例如 NFS)拥有访问权,或者 ...
- javaEE设计模式——门面模式
1.本节内容 门面模式的意图介绍 门面模式带来的好处 门面模式的应用场景 实现模式的3中方式:POJO.无状态与有状态回话Bean门面 有状态与无状态回话Bean门面的重要差别 关于门面模式使用的警告 ...
- Java环境变量-Linux环境
环境变量说明 JAVA_HOME 它指向jdk的安装目录,Eclipse/NetBeans/Tomcat等软件就是通过搜索JAVA_HOME变量来找到并使用安装好的jdk. PATH 作用是指定命令搜 ...
- 基於tiny4412的Linux內核移植--- 中斷和GPIO學習(2)
作者 彭東林 pengdonglin137@163.com 平臺 tiny4412 ADK Linux-4.4.4 u-boot使用的U-Boot 2010.12,是友善自帶的,爲支持設備樹和uIma ...
- docker进入后台运行的容器
转载请注明出处 我们运行docker容器的时候,使用了-d参数,把容器在后台运行后. 这个时候,我们使用docker ps命令,我们就可以知道哪些程序在后台运行. 我们要怎么进入到docker ...
- CentOS7使用firewalld打开关闭防火墙与端口
1.firewalld的基本使用 启动: systemctl start firewalld 查看状态: systemctl status firewalld 停止: systemctl disab ...
- 设置nginx禁止IP直接访问,只能通过指定的域名访问
nginx的版本是1.2.1. 设置配置文件disableip.conf: server { listen 80; server_name _; return500; } 这是 ...
- MongoDB初识
参考: MongoDB资料汇总专题:
- FastSocket学习笔记~再说客户端与服务端的组成
废话多说 很久之前,我写过几篇FastSocket的文章,基本属于使用的方法,而缺乏对概念的总结讲解,而本讲就是弥补一下上几讲的不足,将核心的模块再说说,再谈谈,再聊聊! 首先FastSocket由C ...