延迟队列实现

延迟队列一般用来做超时处理,比如订单超时后的处理;

JDK DelayQueue
public static DelayQueue<DelayTask> delayQueue = new DelayQueue();

    public static void main(String[] args) {
        delayQueue.add(new DelayTask( "task1",System.currentTimeMillis() + 1000));
        delayQueue.add(new DelayTask( "task2",System.currentTimeMillis() + 5000));
        while (!delayQueue.isEmpty()) {
            try {
                System.out.println("Waiting for task..."+System.currentTimeMillis());
                DelayTask task = delayQueue.take();
                System.out.println("Task: " + task.taskKey + " is ready to be executed"+System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    static class DelayTask implements Delayed {
        public String taskKey;
        public long delayTime;

        public DelayTask(String taskKey,long delayTime) {
            this.delayTime = delayTime;
            this.taskKey = taskKey;
        }

        @Override
        public long getDelay(TimeUnit unit) {
            long diff = delayTime - System.currentTimeMillis();
            return unit.convert(diff, TimeUnit.MILLISECONDS);
        }

        @Override
        public int compareTo(Delayed other) {
            if (this.delayTime < ((DelayTask) other).delayTime) {
                return -1;
            }
            if (this.delayTime > ((DelayTask) other).delayTime) {
                return 1;
            }
            return 0;
        }
    }
redis实现
public void redisDelayDemo() {
        String queueName = "delay_queue";
        // 添加任务  这里当前时间+10秒 作为数据权重, 后续取值时以当前时间作为权重来取 就可以10秒后取到任务
        redisTemplate.opsForZSet().add(queueName, "task1", Instant.now().getEpochSecond() + 10);

        // 循环获取任务
        new Thread(() -> {
            while (true) {
                Set<String> taskList = redisTemplate.opsForZSet().rangeByScore(queueName, 0, Instant.now().getEpochSecond());
                log.info("taskList:{}", taskList);
                try {
                    // 根据实时性要求调整sleep时间
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }).start();
    }
mq

rabbitMq和sqs可以通过设置ttl,让消息过期到达死信队列,再实时去消费死信队列的消息;

rocketMq  Delayed Message 

        可以设置message.setDelayTime 参数对应的broker.conf中的messageDelayLevel,比如1 就是对应其中的第一个值,单位秒

Redis Sorted Set作为延迟队列的优点:

  1. 轻量级:Redis是一个内存数据库,Sorted Set作为一种数据结构,相对于完整的消息队列系统来说,更加轻量级,部署和维护成本可能更低。

  2. 集成方便:如果你的应用已经在使用Redis,那么利用Redis的Sorted Set作为延迟队列可以方便地集成到现有架构中。

  3. 快速响应:Redis是内存数据库,对于读写操作有着很快的响应时间,适合对实时性要求较高的场景。

  4. 灵活性:你可以利用Redis的其他功能,如发布/订阅、持久化等,来扩展延迟队列的功能,满足更多的需求。

MQ的死信队列的优点:

  1. 专业性:消息队列系统专注于消息传递和处理,有更丰富的功能和更完善的管理工具,更适合在大规模、复杂的系统中使用。

  2. 可靠性:消息队列系统通常具有高可用性、持久化等特性,能够保证消息的可靠传递和处理,对于关键业务场景更可靠。

  3. 管理工具:消息队列系统通常提供丰富的管理工具和监控功能,能够方便地监控消息的状态、重试失败的消息等。

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值