springBoot使用redis的key过期通知功能

背景:项目中有一个触发+执行动作功能,  当条件被触发后 可以设置时间  延时执行动作.

思考了一下,有以下几种方式:

  • Quartz 任务调度框架,更适合周期性的执行任务,对于订单超时未支付,只能采用5分钟一轮询数据库的形式实现
  • Timer java原生定时工具,可少量使用,当数据量大时,性能不好控制
  • Quartz + Timer 周期轮询(5分钟)数据库,查询出5分钟之内将要超时的订单,然后多线程创建timer完成订单的定时,这种实现方式比较复杂,但是可以在性能和功能方面,是可以实现的
  • reids 键空间通知 以下将介绍此种方式

1,加入依赖

        
            org.springframework.boot
            spring-boot-starter-data-redis
            1.5.10.RELEASE
        

2.创建两个类

RedisKeyExpirationListener

package com.star.re.redis;

import org.apache.log4j.Logger;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import com.star.common.utils.RedisUtil;
import com.star.re.utils.RuleFilterThread;
import com.star.re.utils.RuleUtils;

@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    private static Logger logger = Logger.getLogger(RedisKeyExpirationListener.class);
    
    /**
     * redis key失效,监听
     * @param message
     * @param pattern
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        // 业务处理 , 注意message.toString()可以获取失效的key
        String expiredKey = message.toString();
        logger.info(expiredKey + "----动作触发,开始执行");
        RuleUtils.executeActionByKey(expiredKey);
    }
}

RedisListenerConfig

package com.star.re.redis;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

@Configuration
public class RedisListenerConfig {
	
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {

        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }
}

3.redis配置

在源码目录中有一个模板redis.conf,对它进行改动就可以了。
官方文档中说Keyspace notifications功能默认是关闭的(默认地,Keyspace 时间通知功能是禁用的,因为它或多或少会使用一些CPU的资源),我们需要打开它。打开的方法也很简单,配置属性:notify-keyspace-events

默认配置是这样的:notify-keyspace-events ""
根据文档中的说明:

K     Keyspace events, published with __keyspace@__ prefix.
E     Keyevent events, published with __keyevent@__ prefix.
g     Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
$     String commands
l     List commands
s     Set commands
h     Hash commands
z     Sorted set commands
x     Expired events (events generated every time a key expires)
e     Evicted events (events generated when a key is evicted for maxmemory)
A     Alias for g$lshzxe, so that the "AKE" string means all the events.

我们配置为:notify-keyspace-events Ex,含义为:发布key事件,使用过期事件(当每一个key失效时,都会生成该事件)。\

springBoot使用redis的key过期通知功能_第1张图片

然后重启即可.

其他参考:https://www.jianshu.com/p/106f0eae07c8

你可能感兴趣的:(定时任务,redis,缓存)