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 );
}
相關文章
相關標籤/搜索