通过redis键空间通知实现日程的提醒通知

2022/4/15 19:13:10

本文主要是介绍通过redis键空间通知实现日程的提醒通知,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

什么是延迟任务?

顾明思议,我们把需要延迟执行的任务叫做延迟任务

延迟任务的使用场景有以下这些:

  1. 红包 24 小时未被查收,需要延迟执退还业务;
  2. 每个月账单日,需要给用户发送当月的对账单;
  3. 订单下单之后 30 分钟后,用户如果没有付钱,系统需要自动取消订单。
  4. 新增日程事项选择某个时间后,需要到点或提前多久,或每天,或每周等,发送当前日程通知。

等事件都需要使用延迟任务。

使用 Redis 实现延迟任务的方法大体可分为两类:

  1. 和通过键空间通知的方式
  2. 通过 zset 数据判断的方式。

 1.通过键空间通知

默认情况下 Redis 服务器端是不开启键空间通知的,需要我们通过 config set notify-keyspace-events Ex 的命令手动开启,

开启键空间通知后,我们就可以拿到每个键值过期的事件,我们利用这个机制实现了给每个人开启一个定时任务的功能,实现代码如下:

import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;


/*
* redis数据连接池的工具类
* 这个有点老
* @author lcl
*/
@Component
public class JedisUtils {

    private static JedisPool pool;

    static {
        //读取配置文件
        String host = "localhost";
        //获取端口号
        int port = Integer.parseInt("6379");

        //获取最大连接数
        int maxTotal = Integer.parseInt("50");
        //获取闲时连接数
        int maxIdle = Integer.parseInt("20");

        //创建连接池配置对象
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxTotal(maxTotal);

        //创建连接池对象
        pool = new JedisPool(jedisPoolConfig, host, port);
    }
    //创建方法  连接池对象
    public static Jedis getJedis(){
        return pool.getResource();
    }

    //释放资源
    public static void close(Jedis jedis){
        if(jedis!=null){
            jedis.close();
        }
    }

    private static void close(JedisPool pool){
        if (pool!=null){
            pool.close();
        }
    }
}

 Service

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

/**
 * 通过redis实现 定时任务发送通知
 * @author lcl
 */
@Component
public class RedisTaskServiceImpl implements ApplicationRunner
{

    private static final Logger log = LoggerFactory.getLogger(RedisTaskServiceImpl.class);

    /**
     * 键空间通知
     */
    public void doTask()
    {
        //连接redis的工具类,你得自己设置一下
        Jedis jedis = JedisUtils.getJedis();
        // 订阅过期消息
        jedis.psubscribe(new JedisPubSub()
        {
            @Override
            public void onPMessage(String pattern, String channel, String message)
            {
                /**
                 *    我存了两个key
                 *    一个是过期时间的,一个是不过期的
                 *    如:
                 *    rediskey      会过期
                 *    rediskey_01   不会过期
                 *    根据接收到过期的key,可以通过 key + _01 你存储的标识
                 *    得到副key,然后就可以得到value值进行业务等操作,用完就可以删除
                 */
                log.info("收到消失的key:" + message);

            }
            //__keyevent@0__:expired 为你的 redis 订阅频道名称 默认一般是 0这个数据库,分库的后面在想想办法吧
        }, "__keyevent@0__:expired");
    }


    /**
     * springboot项目启动时跟着启动
     * @param args
     * @throws Exception
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        doTask();
    }
}

模拟执行测试

启动项目

 redis有数据

 等到时间到了后,就会执行

 键空间通知就是这样,主要还是这命令总忘记执行,还有另一种方法,就是配置conf文件,省的每次重启redis都要执行这代码

 config set notify-keyspace-events Ex 

2.通过 zset 数据

 目前还没用到,后期业务上用到了在补充吧 

 



这篇关于通过redis键空间通知实现日程的提醒通知的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程