• 十一、RabbitMq优先级队列


    使用场景

    在我们系统中有一个订单催付的场景,我们的客户在天猫下的订单,淘宝会及时将订单推送给我们,如果在用户设定的时间内未付款那么就会给用户推送一条短信提醒,很简单的一个功能对吧,但是,tmall商家对我们来说,肯定是要分大客户和小客户的对吧,比如像苹果,小米这样大商家一年起码能给我们创造很大的利润,所以理应当然,他们的订单必须得到优先处理,而曾经我们的后端系统是使用 redis 来存放的定时轮询,大家都知道 redis 只能用 List 做一个简简单单的消息队列,并不能实现一个优先级的场景,所以订单量大了后采用 RabbitMQ 进行改造和优化,如果发现是大客户的订单给一个相对比较高的优先级,否则就是默认优先级。

    如何添加

    控制台页面添加

    优先级队列-控制台

    队列中代码添加优先级

    Map<String, Object> params = new HashMap();
    params.put("x-max-priority", 10);
    channel.queueDeclare("hello", true, false, false, params);
    

    优先级队列-队列中代码添加

    消息中代码添加优先级

    AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().priority(5).build();
    

    注意事项

    要让队列实现优先级需要做的事情有如下事情:队列需要设置为优先级队列,消息需要设置消息的优先级,消费者需要等待消息已经发送到队列中才去消费因为,这样才有机会对消息进行排序

    实战

    消息生产者

    public class Producer {
        private static final String QUEUE_NAME = "hello";
    
        public static void main(String[] args) throws Exception {
            try (Channel channel = RabbitMqUtils.getChannel();) {
                //给消息赋予一个 priority 属性
                AMQP.BasicProperties properties = new
                        AMQP.BasicProperties().builder().priority(5).build();
                for (int i = 1; i < 11; i++) {
                    String message = "info" + i;
                    if (i == 5) {
                        channel.basicPublish("", QUEUE_NAME, properties, message.getBytes());
                    } else {
                        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
                    }
                    System.out.println("发送消息完成:" + message);
                }
            }
        }
    }
    

    消息消费者

    public class Consumer {
        private static final String QUEUE_NAME = "hello";
    
        public static void main(String[] args) throws Exception {
            Channel channel = RabbitMqUtils.getChannel();
            //设置队列的最大优先级 最大可以设置到 255 官网推荐 1-10 如果设置太高比较吃内存和 CPU
            Map<String, Object> params = new HashMap();
            params.put("x-max-priority", 10);
            channel.queueDeclare(QUEUE_NAME, true, false, false, params);
            System.out.println("消费者启动等待消费......");
            DeliverCallback deliverCallback = (consumerTag, delivery) -> {
                String receivedMessage = new String(delivery.getBody());
                System.out.println("接收到消息:" + receivedMessage);
            };
            channel.basicConsume(QUEUE_NAME, true, deliverCallback, (consumerTag) -> {
                System.out.println("消费者无法消费消息时调用,如队列被删除");
            });
        }
    }
    
  • 相关阅读:
    添加AdMob的Native广告
    androidx.recyclerview.widget.RecyclerView的使用方法
    androidx.recyclerview.widget.RecyclerView 使用记录
    ViewPager使用
    小程序加载云端数据库中的第二页数据,前端如何动态显示?
    小程序页面跳转传递参数
    小程序云端函数 where遇到的问题
    Python 加载包含多个JSON对象的JSON文件
    如何把一个目录下的中文名字的文件全部变成拼音命名的文件?
    小技巧--解决eclipse导入的jar文件后,无法使用默认包中的方法问题
  • 原文地址:https://www.cnblogs.com/linhp/p/15245734.html
Copyright © 2020-2023  润新知