SpringBoot实现监听redis key失效事件

需求:

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

解决方案1:

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

开启redis key过时提醒

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

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.定义配置RedisListenerConfigspringboot

 

  

@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接口


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 );
}
相关文章
相关标签/搜索