序:
這次遇到的場景是需要對redis的失效key做比對判斷,增加電業務邏輯。
廢話不多說,直接說重點,我也趕着回家呢。
redis配置文件修改,我是win系統。這個是對redis版本有要求的,所以先查看版本信息。
查看redis版本信息,redis安裝目錄下,黑框框(你懂的)下運行redis-cli.exe,然後再輸入info
這個實際上是高版本的redis的消息隊列的一種使用。redis版本要求2.8.0以上,我這裏裝的是3.2.100
redis配置文件修改,找到redis.windows.conf文件,用記事本類工具打開。
重啓redis服務,注意要帶配置文件哦,很多人起服務不帶這個redis配置文件,所以每次重啓裏面的key都丟失了。
驗證是否會有監聽
還是在剛剛輸入info命令的黑框框繼續輸入 psubscribe "__keyevent@*:expired",回車。你會看到
然後,配合redis Desktop Manager看效果,打開這個工具,連接上redis後,打開命令行
看到效果沒,我在命令行輸入用命令設置一個3秒超時的key value,然後黑框框3s後就有反應了。
上面講的基本是原理,下面上java代碼
springBoot增加一個配置,上次說到過redis增加配置,真是簡單,方便的不要不要的,直接在config包下增加一個配置類RedisListenerConfig類,代碼如下:
package com.filler.config;
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.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import com.filler.listenner.RedisExpiredListener;
@Configuration
public class RedisListenerConfig {
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//下面這種方式是靈活配置,針對每個庫的失效key做處理
//container.addMessageListener(new RedisExpiredListener(), new PatternTopic("__keyevent@0__:expired"));
return container;
}
}
然後我建了一個listenner的包,在下面增加一個監聽類:
package com.filler.listenner;
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;
/**
* redis失效key監聽
*
* @author 鄭文
*
*/
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
/**
* redis失效key事件處理
* @param message
* @param pattern
*/
@Override
public void onMessage(Message message, byte[] pattern) {
// message.toString()可以獲取失效的key
String expiredKey = message.toString();
System.out.println("-------------------");
System.out.println("失效key:"+expiredKey);
}
}
還有一個監聽類,是配合上面的配置文件註釋的部分的,可以靈活配置,配置監聽不同的庫,redis有16個庫。
package com.filler.listenner;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
public class RedisExpiredListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] bytes) {
byte[] body = message.getBody();// 建議使用: valueSerializer
byte[] channel = message.getChannel();
System.out.print("onMessage >> " );
System.out.println(String.format("channel: %s, body: %s, bytes: %s"
,new String(channel), new String(body), new String(bytes)));
}
}
ok了,代碼寫完了,看看效果,還是用redis Desktop Manager配合java代碼
看到效果了吧。然後你就可以在你的監聽類裏判斷失效key的特徵,寫自己的業務邏輯。唯一遺憾的是不能難道value,也能夠理解,實際就是redis刪除失效key做了一個通知主題被java感知了。以後有個redis失效key的前置事件就好了。現在變相的處理方式,可以約定業務存2個key,一個有失效時間,一個沒有,比如存win這個key時,還存一個win_val可以,在失效監聽裏自己再去取win_val的value消費,消費完成後刪除這個win_val的key。
好了就到這裏了,剩下的業務邏輯就可以fly your self了。