起因
最近寒假没事干,写了一个靶场项目,关于创建一个容器时,会给它一个半个小时的到期时间,这里就有了定时的需求,我需要在靶场到期的时候对它进行删除
想了很多办法,什么用springboot的定时任务每秒去数据库中查询到期时间对比现在的时间进行删除,虽然这样实现起来简单,但这样太耗性能了;还有那啥RebbitMQ延迟死信,我就一个简单的倒计时操作,没必要大费周章创建一个那么大的应用
过程
最后想到redis自带一个倒计时的功能,而他也自带一个监听过期的功能,就像发现新大陆一样又回去复习了redis
实现
首先在pom.xml中加上redis的依赖
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.6.3</version>
</dependency>
配置application
spring.redis.host=服务器
spring.redis.port=6379
spring.redis.password=你的密码
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.timeout=30000
接下来直接上代
码,创建一个RedisConfig文件,用于存放redis配置。
这段代码RedisMessageListenerContainer
用于开启监听功能;
RedisTemplate
这段是为了配置序列化,如果不配置,java默认会使用jdk序列化,比如在创建一个键值对的时候会自动在你的key value前加上一些16进制的字符串,对我们后续的监听造成困扰
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Autowired
RedisConnectionFactory redisConnectionFactory;
/*
redis开启监听配置
*/
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(){
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
return redisMessageListenerContainer;
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 序列化配置开始
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
// 序列化配置结束
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
下方开始配置监听接收到的内容代码
@Component
public class RedisKeyExpiration extends KeyExpirationEventMessageListener {
private static SafeDockerUserService safeDockerUserService; // 使用方法在这里完成注入
@Autowired
public void setRedisService (SafeDockerUserService safeDockerUserService){
RedisKeyExpiration.safeDockerUserService= safeDockerUserService;
}
public RedisKeyExpiration(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
// 这是继承KeyExpirationEventMessageListener 主动重写的方法,用于处理当监听到了Key失效的时间
@Override
public void onMessage(Message message, byte[] pattern) {
super.onMessage(message, pattern);
// 在这里我们可以放我们的逻辑代码,执行一些到期后需要执行的操作
if (message.toString().startsWith("codetip:safe:labs:")){
System.out.println("监听到靶场到期,id为:"+message.toString().split("codetip:safe:labs:")[1]);
}
}
}
配置好后,我们启动应用,使用redis控制台创建一个倒计时的key查看效果
setex codetip:safe:labs:id 10 true