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

3 篇文章 0 订阅
1 篇文章 0 订阅

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

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

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

1,加入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>1.5.10.RELEASE</version>
        </dependency>

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@<db>__ prefix.
E     Keyevent events, published with __keyevent@<db>__ 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失效时,都会生成该事件)。\

然后重启即可.

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
可以使用 Spring Data Redis 提供的 @EnableRedisRepositories 注解,同时实现 RedisKeyExpirationListener 接口,并在 @Configuration 类中添加监听器配置。 以下是代码片段示例: @Configuration @EnableRedisRepositories public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(jedisConnectionFactory()); return template; } @Bean public JedisConnectionFactory jedisConnectionFactory() { return new JedisConnectionFactory(); } @Bean public RedisMessageListenerContainer redisContainer() { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(jedisConnectionFactory()); return container; } @Bean RedisKeyExpirationListener keyExpirationListener() { return new RedisKeyExpirationListener(); } @Bean MessageListenerAdapter listenerAdapter(RedisKeyExpirationListener keyExpirationListener) { return new MessageListenerAdapter(keyExpirationListener); } @Bean RedisMessageListenerContainer keyExpirationContainer(RedisKeyExpirationListener keyExpirationListener, MessageListenerAdapter listenerAdapter) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(jedisConnectionFactory()); container.addMessageListener(listenerAdapter, new PatternTopic("__keyevent@*:expired")); return container; } private static class RedisKeyExpirationListener implements MessageListener { @Override public void onMessage(Message message, byte[] pattern) { String expiredKey = message.toString(); // 处理过期key逻辑 } } } 这里我们定义了一个 RedisContainer 和一个 RedisKeyExpirationListener,然后将 RedisKeyExpirationListener 获取到的过期 key 进行处理。ListenAdapter 和 keyExpirationContainer 主要是为了配置监听器,其中"__keyevent@*:expired"用来监听所有 Redis 中发生的 key 过期事件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值