redis的订阅-键失效
核心需求:判断设备的超时状态
当有新数据流入时,判断是否已经存在,不存在自动存入redis,已经存在的话就覆写,然后设置一个过期时间,每次键过期时,要对过期的数据进行处理,这里的处理逻辑是这样的,首先判断这个数据过期了几次,小于三次的话,就只让他在redis里面的重连次数加一,如果次数已经大于3次了,那么判断这个数据无效,删除MySQL数据库里面的数据。
核心代码
前提:把redis配置文件中的键过期推送打开,具体可以百度。如果还不懂可以私信~
这里是基于springboot实现的一套监听逻辑,还有一套用java原生实现的,相对要麻烦很多,在这就不展示了~
pom文件:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.7.2</version>
</dependency>
写入redis的代码:
@Controller
public class demo {
@Autowired
RedisConnectionFactory redisConnectionFactory;
@Autowired
private RedisConfig redisConfig;
@RequestMapping("/de/{key}/{value}")
@ResponseBody
public void dd(@PathVariable("key") String key,@PathVariable("value") String value){
RedisTemplate<String, Object> redisTemplate = redisConfig.redisTemplate(redisConnectionFactory);
redisTemplate.opsForValue().set(key,"",5, TimeUnit.SECONDS);
}
}
redis的配置代码:
主要是配置序列器,如果不配置,会有key乱码的现象存在,最好还是配置一个
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
// 创建 RedisTemplate 对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 设置连接工厂
template.setConnectionFactory(connectionFactory);
// 创建 JSON 序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
// 设置 key 的序列化
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
// 设置 value 的序列化
template.setValueSerializer(jsonRedisSerializer);
template.setHashValueSerializer(jsonRedisSerializer);
// 返回
return template;
}
}
监听器的配置代码:
@Configuration
public class RedisListenerConfig {
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
}
下面是监听器的具体实现,也就是业务代码
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
@Autowired
RedisConnectionFactory redisConnectionFactory;
@Autowired
private RedisConfig redisConfig;
private static Set<String> outset = new HashSet<>();
private PreparedStatement preparedStatement;
private static DruidDataSource ds;
private Logger LOG = LoggerFactory.getLogger(RedisKeyExpirationListener.class);
private Connection conn;
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
/**
* 针对redis数据失效事件,进行数据处理
* @param message
* @param pattern
*/
@Override
public void onMessage(Message message, byte[] pattern) {
// 这地方可以做自己的业务处理,message.toString()可以获取失效的key
RedisTemplate<String, Object> redisTemplate = redisConfig.redisTemplate(redisConnectionFactory);
String expiredKey = message.toString();
//System.out.println("过期redis_key: " + expiredKey);
//LOG.info("过期redis_key: " + expiredKey);
//业务逻辑
}
}
yaml的配置文件:
spring:
redis:
host: localhost
port: 6379
database: 0
lettuce:
pool:
max-active: 100
max-wait: -1ms
max-idle: 8
min-idle: 1
timeout: PT10S
password: password
整体逻辑不难,属于谁来谁也会,但是实操还是各种问题的问题,哈哈,欢迎留言讨论~~~