阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

强大的RabbitMQ优先级队列让你轻松面对现实业务场景

198次阅读
没有评论

共计 3511 个字符,预计需要花费 9 分钟才能阅读完成。

说到队列的话,大家一定不会陌生,但是扯到优先级队列的话,还是有一部分同学是不清楚的,可能是不知道怎么去实现吧,其实呢,这东西已经烂大街了。很简单,用“堆”去实现的,在我们系统中有一个订单催付的场景,我们客户的客户在 tmall,taobao 下的订单,taobao 会及时将订单推送给我们,如果在用户设定的时间内未付款那么就会给用户推送一条短信提醒,很简单的一个功能对吧,但是,tmall 商家对我们来说,肯定是要分大客户和小客户的对吧,比如像施华蔻,百雀林这样大商家一年起码能够给我们贡献几百万,所以理应当然,他们的订单必须得到优先处理,而曾今我们的后端系统是使用 redis 来存放的定时轮询,大家都知道 redis 只能用 List 做一个简简单单的消息队列,并不能实现一个优先级的场景,所以订单量大了后采用 rabbitmq 进行改造和优化, 如果发现是大客户的订单给一个相对比较高的优先级,否则就是默认优先级,好了,废话不多说,我们来看看如何去设置。

一:优先级队列

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

手工的创建优先级队列。

强大的 RabbitMQ 优先级队列让你轻松面对现实业务场景

      从这个图中可以看到在 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);

强大的 RabbitMQ 优先级队列让你轻松面对现实业务场景

 

通过上面的代码可以看到,在 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();}

强大的 RabbitMQ 优先级队列让你轻松面对现实业务场景

 

图中可以看到 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();}

强大的 RabbitMQ 优先级队列让你轻松面对现实业务场景

 

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

强大的 RabbitMQ 优先级队列让你轻松面对现实业务场景

 

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

CentOS 5.6 安装 RabbitMQ http://www.linuxidc.com/Linux/2013-02/79508.htm

RabbitMQ 客户端 C ++ 安装详细记录 http://www.linuxidc.com/Linux/2012-02/53521.htm

用 Python 尝试 RabbitMQ http://www.linuxidc.com/Linux/2011-12/50653.htm

RabbitMQ 集群环境生产实例部署 http://www.linuxidc.com/Linux/2012-10/72720.htm

Ubuntu 下 PHP + RabbitMQ 使用 http://www.linuxidc.com/Linux/2010-07/27309.htm

在 CentOS 上安装 RabbitMQ 流程 http://www.linuxidc.com/Linux/2011-12/49610.htm

RabbitMQ 概念及环境搭建 http://www.linuxidc.com/Linux/2014-12/110449.htm

RabbitMQ 入门教程  http://www.linuxidc.com/Linux/2015-02/113983.htm

RabbitMQ 的详细介绍 :请点这里
RabbitMQ 的下载地址 :请点这里

 

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计3511字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中