Redis 配置
方法一、更改配置文件,以配置文件启动
进入 Redis 安装目录,修改 redis.windows.conf
(Linux 下配置文件是 redis.conf
)
在第892行找到 notify-keyspace-events
(Windows 系统,Redis 版本 5.0.10)
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
以配置文件启动
redis-server redis.windows.conf
方法二、在 redis-cli 中配置
运行 redis-cli
,运行命令
config set notify-keyspace-events Ex
或在终端直接运行命令
redis-cli config set notify-keyspace-events Ex
Spring Boot 监听
引入依赖
<!-- maven -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
// gradle
compile("org.springframework.boot:spring-boot-starter-data-redis")
RedisMessageListener.java
@Component
public class RedisMessageListener implements MessageListener {
@Resource
private RedisTemplate<String, Object> redis;
@Override
public void onMessage(Message message, byte[] pattern) {
System.out.println("----------- " + new String(pattern));
// 使用了 fastjson 来打印对象
System.out.println(JSONObject.toJSONString(message, true));
System.out.println("-------------------------------");
// 获取过期的键
System.out.println(redis.getKeySerializer().deserialize(message.getBody()));
}
}
RedisConfig.java
@Configuration
public class RedisConfig {
@Resource
private RedisMessageListener messageListener;
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(new StringRedisSerializer());
final Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
template.setValueSerializer(serializer);
return template;
}
@Bean
public ChannelTopic channelTopic() {
// 监听 Redis 键过期事件通知
return new ChannelTopic("__keyevent@0__:expired");
}
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory) {
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
redisMessageListenerContainer.addMessageListener(messageListener, channelTopic());
return redisMessageListenerContainer;
}
}
运行测试
方法1、在 redis-cli 中操作
set 123 456 PX 100
键 123,值 456,100ms 后过期,若 PX
设为 EX
则时间单位为秒。
方法2、使用 Spring Boot 操作
@RestController
public class TestController {
@Resource
private RedisTemplate<String, Object> redis;
@GetMapping("/redis")
public void re() {
ValueOperations<String, Object> ops = redis.opsForValue();
ops.set("123", "456");
// 设置需要过期的键,过期时间,时间单位
redis.expire("123", 100L, TimeUnit.MILLISECONDS);
}
}
运行结果
控制台打印
----------- __keyevent@0__:expired
{
"body":"MTIz",
"channel":"X19rZXlldmVudEAwX186ZXhwaXJlZA=="
}
-------------------------------
123
成功拿到过期的键 123。
注意事项
Spring Boot 2.6 默认禁止了循环引用,需要配置开启循环引用。
spring:
main:
allow-circular-references: true