业务日记——延时队列/延时消费

本文介绍了延时/定时消息的基本定义和常见使用场景,如任务超时处理和延时处理。接着详细讨论了几种实现方式,包括数据库轮询、JDK的DelayQueue和ScheduledExecutorService、Redis的ZSet以及RabbitMQ的延时队列。每种方式都有其优缺点,如数据库轮询简单但效率低,DelayQueue和ScheduledExecutorService线程安全但可能受任务执行时间影响,Redis的ZSet适合分布式环境,而RabbitMQ则利用死信队列实现延时消费。
摘要由CSDN通过智能技术生成
一、基本定义

延时/定时消息是指生产者(producer)发送消息到server后,server并不将消息立即发送给消费者(consumer),而是在producer指定的时间之后送达。

二、常用的使用场景
  • 任务超时处理。例如 订单系统中,如果某个用户在 30分钟内没有支付,则订单自动进行过期处理
  • 任务延时处理。例如订餐系统中,下单成功60s之后 给用户发短信通知
  • 定时任务。例如现在通过手机发送指令,在30分钟之后开启空调之类的。
三、实现方式

一般常用的有一下几种方式

  • 定时器轮询遍历数据库记录
  • JDK的DelayQueue
  • JDK的ScheduledExecutorService
  • Redis的ZSet实现
  • RabbitMQ的延时队列
  • 时间轮(netty/kafka等)
3.1 数据库轮询

比较简单常用的方式,把相对应的消息体存放在数据库中。然后启一个线程定时去扫数据库。找到超时的数据,做相对应的业务处理。

优点

  • 方式很简单,不会引入其他的技术,开发周期短。

缺点

  • 数据量过大时会消耗太多的IO资源,效率太低
  • 而且当数量过大的时候,定时误差也较大
3.2 基于JDK的DelayQueue

Java中的DelayQueue位于java.util.concurrent包下,作为单机实现,它很好的实现了延迟一段时间后触发事件的需求。并且是线程安全,它可以有多个消费者和多个生产者,从而在某些情况下可以提升性能。
DelayQueue本质是封装了一个PriorityQueue。用户排序。这样可以保证后来插入消息的但是延时时间更短的会在前面。内部使用最小堆来实现排序队列,队首的,最先被消费者拿到的就是最小的那个。使用最小堆让队列在数据量较大的时候比较有优势。时间复杂度相对都比较好,都是O(logN)。

实现伪代码如下:

public class MyDelayed implements Delayed{
   
     // 延迟的时间
    private long delayTime;
     //进入队列的时间
    private long enterTime;
	 @Override
    public int compareTo(Delayed o) {
   
        return (int) (this.getDelay(TimeUnit.MILLISECONDS) -o.getDelay(TimeUnit.MILLISECONDS));
    }
	/**
     * 返回只小于等于0表示当前时间已经过去
     */
    @Override
    public long getDelay(TimeUnit unit) {
   
        long expire = this.enterTime + delayTime;
        return unit.convert(expire - System.currentTimeMillis(),TimeUnit.MILLISECONDS);
    }
	// ...中间省略
	//实现方式
	DelayQueue<MyDelayed> delayQueue = new DelayQueue<>();
	delayQueue.add(new MyDelayed(5000));
  	while (delayQueue.size() 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值