服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Redis - 分布式利器redis及redisson的延迟队列实践

分布式利器redis及redisson的延迟队列实践

2022-03-01 22:54kl Redis

这篇文章为大家主要介绍了分布式利器redis及redisson的延迟队列实践,搜遍全网好像还没有使用redisson的延迟队列的,redisson作为一个分布式利器,这么好用的工具没人用有点可惜

前言碎语

首先说明下需求,一个用户中心产品,用户在试用产品有三天的期限,三天到期后准时准点通知用户,试用产品到期了。这个需求如果不是准时通知,而是每天定点通知就简单了。如果需要准时通知就只能上延迟队列了。使用场景除了如上,典型的业务场景还有电商中的延时未支付订单失效等等。

延迟队列多种实现方式

  • 1.如基于RabbitMQ的队列ttl+死信路由策略:通过设置一个队列的超时未消费时间,配合死信路由策略,到达时间未消费后,回会将此消息路由到指定队列
  • 2.基于RabbitMQ延迟队列插件(rabbitmq-delayed-message-exchange):发送消息时通过在请求头添加延时参数(headers.put("x-delay", 5000))即可达到延迟队列的效果
  • 3.使用redis的zset有序性,轮询zset中的每个元素,到点后将内容迁移至待消费的队列,(redisson已有实现)
  • 4.使用redis的key的过期通知策略,设置一个key的过期时间为延迟时间,过期后通知客户端

redisson中的延迟队列实现

怎么封装便于业务使用。

1.首先定义一个延迟job,里面包含一个map参数,和队列执行器的具体实现class,触发任务执行时,map参数会被传递到具体的业务执行器实现内

?
1
2
3
4
5
6
7
8
/**
 * Created by kl on 2018/7/20.
 * Content :延时job
 */
public class DelayJob {
    private Map jobParams;//job执行参数
    private Class aClass;//具体执行实例实现
}

2.定义一个延迟job执行器接口,业务需要实现这个接口,然后在execute方法内写自己的业务逻辑

?
1
2
3
4
5
6
7
/**
 * Created by kl on 2018/7/20.
 * Content :延时job执行器接口
 */
public interface ExecuteJob {
     void execute(DelayJob job);
}

3.消费已经到点的延时job服务,通过job参数调用业务执行器实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@Component
public class JobTimer {
    static final String jobsTag = "customer_jobtimer_jobs";
    @Autowired
    private RedissonClient client;
    @Autowired
    private ApplicationContext context;
    ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
    @PostConstruct
    public void startJobTimer() {
        RBlockingQueueblockingQueue = client.getBlockingQueue(jobsTag);
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    try {
                        DelayJob job = blockingQueue.take();
                        executorService.execute(new ExecutorTask(context, job));
                    } catch (Exception e) {
                        e.printStackTrace();
                        try {
                            TimeUnit.SECONDS.sleep(60);
                        } catch (Exception ex) {
                        }
                    }
                }
            }
        }.start();
    }
    class ExecutorTask implements Runnable {
        private ApplicationContext context;
        private DelayJob delayJob;
        public ExecutorTask(ApplicationContext context, DelayJob delayJob) {
            this.context = context;
            this.delayJob = delayJob;
        }
        @Override
        public void run() {
            ExecuteJob service = (ExecuteJob) context.getBean(delayJob.getaClass());
            service.execute(delayJob);
        }
    }
}

4.封装延时job服务

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * Created by kl on 2018/7/20.
 * Content :延时job服务
 */
@Component
public class DelayJobService {
    @Autowired
    private RedissonClient client;
    public void submitJob(DelayJob job, Long delay, TimeUnit timeUnit){
        RBlockingQueueblockingQueue = client.getBlockingQueue(JobTimer.jobsTag);
        RDelayedQueue delayedQueue = client.getDelayedQueue(blockingQueue);
        delayedQueue.offer(job,delay,timeUnit);
    }
}

文末结语

redisson作为一个分布式利器,这么好用的工具没人用有点可惜,还有一个原因是有个想法,想将延迟队列这个功能封装成一个spring boot的start依赖,然后开源出来,造福四方,希望大家以后多多支持服务器之家!

原文链接:http://www.kailing.pub/article/index/arcid/207.html

延伸 · 阅读

精彩推荐
  • RedisLinux Redis 的安装步骤详解

    Linux Redis 的安装步骤详解

    这篇文章主要介绍了 Linux Redis 的安装步骤详解的相关资料,希望大家通过本文能掌握如何安装Redis,需要的朋友可以参考下 ...

    carl-zhao3822019-11-08
  • RedisRedis存取序列化与反序列化性能问题详解

    Redis存取序列化与反序列化性能问题详解

    这篇文章主要给大家介绍了关于Redis存取序列化与反序列化性能问题的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参...

    这名字已经存在9742021-02-24
  • Redisredis启动,停止,及端口占用处理方法

    redis启动,停止,及端口占用处理方法

    今天小编就为大家分享一篇redis启动,停止,及端口占用处理方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 ...

    澄海单挑狂5152019-11-14
  • Redis聊一聊Redis与MySQL双写一致性如何保证

    聊一聊Redis与MySQL双写一致性如何保证

    一致性就是数据保持一致,在分布式系统中,可以理解为多个节点中数据的值是一致的。本文给大家分享Redis与MySQL双写一致性该如何保证,感兴趣的朋友一...

    mind_programmonkey6432021-08-12
  • Redis就这?Redis持久化策略——AOF

    就这?Redis持久化策略——AOF

    今天为大家介绍Redis的另一种持久化策略——AOF。注意:AOF文件只会记录Redis的写操作命令,因为读命令对数据的恢复没有任何意义...

    头发茂密的刘叔4052021-12-14
  • RedisRedis数据结构之链表与字典的使用

    Redis数据结构之链表与字典的使用

    这篇文章主要介绍了Redis数据结构之链表与字典的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友...

    白泽来了4052021-08-03
  • RedisRedis分布式锁升级版RedLock及SpringBoot实现方法

    Redis分布式锁升级版RedLock及SpringBoot实现方法

    这篇文章主要介绍了Redis分布式锁升级版RedLock及SpringBoot实现,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以...

    等不到的口琴7802021-07-25
  • Redis在ssm项目中使用redis缓存查询数据的方法

    在ssm项目中使用redis缓存查询数据的方法

    本文主要简单的使用Java代码进行redis缓存,即在查询的时候先在service层从redis缓存中获取数据。如果大家对在ssm项目中使用redis缓存查询数据的相关知识感...

    caychen8962019-11-12