SpringBoot实现监听redis key失效事件

需求:

处理订单过期自动取消,比如下单30分钟未支付自动更改订单状态

解决方案1:

可以利用redis天然的key自动过期机制,下单时将订单id写入redis,过期时间30分钟,30分钟后检查订单状态,如果未支付,则进行处理但是key过期了redis有通知吗?答案是肯定的。

开启redis key过期提醒

修改redis相关事件配置。找到redis配置文件redis.conf,查看“notify-keyspace-events”的配置项,如果没有,添加“notify-keyspace-events Ex”,如果有值,添加Ex,相关参数说明如下:

K:keyspace事件,事件以__keyspace@<db>__为前缀进行发布;         
E:keyevent事件,事件以__keyevent@<db>__为前缀进行发布;         
g:一般性的,非特定类型的命令,比如del,expire,rename等;        
$:字符串特定命令;         
l:列表特定命令;         
s:集合特定命令;         
h:哈希特定命令;         
z:有序集合特定命令;         
x:过期事件,当某个键过期并删除时会产生该事件;         
e:驱逐事件,当某个键因maxmemore策略而被删除时,产生该事件;         
A:g$lshzxe的别名,因此”AKE”意味着所有事件。


pom:

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


<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>


<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>compile</scope>
<version>2.9.7</version>
</dependency>
 

在springboot中使用

  1.定义配置RedisListenerConfig

  

@Configuration
public class RedisListenerConfig {

@Autowired
private RedisTemplate redisTemplate;

/**
* 处理乱码
* @return
*/
@Bean
public RedisTemplate redisTemplateInit() {
// key序列化
redisTemplate.setKeySerializer(new StringRedisSerializer());
//val实例化
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

return redisTemplate;
}

@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {

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

2.定义监听器,实现KeyExpirationEventMessageListener接口


@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

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

/**
* 针对redis数据失效事件,进行数据处理
* @param message
* @param pattern
*/
@Override
public void onMessage(Message message, byte[] pattern) {
// 用户做自己的业务处理即可,注意message.toString()可以获取失效的key
String expiredKey = message.toString();
if(expiredKey.startsWith("orderNo:")){
//如果是order:开头的key,进行处理
System.out.println(expiredKey);
String substring = expiredKey.substring(8); //去掉orderNo
System.out.println(substring);
}
}
}


public class Test(){
    @Resource
    private RedisTemplate redisTemplate;
    redisTemplate.opsForValue().set("orderNo:156556263124101022","dadada" ,5, TimeUnit.SECONDS );
}
 
原文地址:https://www.cnblogs.com/NJM-F/p/10442198.html