Redis集群下过期key监听的实现代码
1.前言
在使用redis集群时,发现过期key始终监听不到。网上也没有现成的解决方案。于是想,既然不能监听集群,那我可以建立多个redis连接,分别对每个redis的key过期进行监听。以上做法可能不尽人意,目前也没找到好的解决方案,如果有好的想法,请留言告知哦!不多说,直接贴我自己的代码!
2.代码实现
关于Redis集群配置代码此处不贴,直接贴配置监听类代码!
redis.host1:10.113.56.68 redis.port1:7030 redis.host2:10.113.56.68 redis.port2:7031 redis.host3:10.113.56.68 redis.port3:7032 redis.host4:10.113.56.68 redis.port4:7033 redis.host5:10.113.56.68 redis.port5:7034 redis.host6:10.113.56.68 redis.port6:7035
importorg.springframework.beans.factory.annotation.Value;
importorg.springframework.cache.CacheManager;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.data.redis.cache.RedisCacheManager;
importorg.springframework.data.redis.connection.RedisClusterConfiguration;
importorg.springframework.data.redis.connection.jedis.JedisConnectionFactory;
importorg.springframework.data.redis.core.RedisTemplate;
importorg.springframework.data.redis.listener.RedisMessageListenerContainer;
importorg.springframework.data.redis.serializer.StringRedisSerializer;
importredis.clients.jedis.Jedis;
importredis.clients.jedis.JedisPoolConfig;
importjava.util.Arrays;
/**
*@Authorxiabing5
*@Create2019/8/614:46
*@Desc监听redis中Key过期事件
**/
@Configuration
publicclassRedisListenerConfig{
@Value("${redis.host1}")
privateStringhost1;
@Value("${redis.host2}")
privateStringhost2;
@Value("${redis.host3}")
privateStringhost3;
@Value("${redis.host4}")
privateStringhost4;
@Value("${redis.host5}")
privateStringhost5;
@Value("${redis.host6}")
privateStringhost6;
@Value("${redis.port1}")
privateintport1;
@Value("${redis.port2}")
privateintport2;
@Value("${redis.port3}")
privateintport3;
@Value("${redis.port4}")
privateintport4;
@Value("${redis.port5}")
privateintport5;
@Value("${redis.port6}")
privateintport6;
@Bean
JedisPoolConfigjedisPoolConfig(){
JedisPoolConfigjedisPoolConfig=newJedisPoolConfig();
jedisPoolConfig.setMaxIdle(100);
jedisPoolConfig.setMaxWaitMillis(1000);
returnjedisPoolConfig;
}
//redis-cluster不支持key过期监听,建立多个连接,对每个redis节点进行监听
@Bean
RedisMessageListenerContainerredisContainer1(){
finalRedisMessageListenerContainercontainer=newRedisMessageListenerContainer();
JedisConnectionFactoryjedisConnectionFactory=newJedisConnectionFactory();
jedisConnectionFactory.setHostName(host1);
jedisConnectionFactory.setPort(port1);
jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
jedisConnectionFactory.afterPropertiesSet();
container.setConnectionFactory(jedisConnectionFactory);
returncontainer;
}
@Bean
RedisMessageListenerContainerredisContainer2(){
finalRedisMessageListenerContainercontainer=newRedisMessageListenerContainer();
JedisConnectionFactoryjedisConnectionFactory=newJedisConnectionFactory();
jedisConnectionFactory.setHostName(host2);
jedisConnectionFactory.setPort(port2);
jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
jedisConnectionFactory.afterPropertiesSet();
container.setConnectionFactory(jedisConnectionFactory);
returncontainer;
}
@Bean
RedisMessageListenerContainerredisContainer3(){
finalRedisMessageListenerContainercontainer=newRedisMessageListenerContainer();
JedisConnectionFactoryjedisConnectionFactory=newJedisConnectionFactory();
jedisConnectionFactory.setHostName(host3);
jedisConnectionFactory.setPort(port3);
jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
jedisConnectionFactory.afterPropertiesSet();
container.setConnectionFactory(jedisConnectionFactory);
returncontainer;
}
@Bean
RedisMessageListenerContainerredisContainer4(){
finalRedisMessageListenerContainercontainer=newRedisMessageListenerContainer();
JedisConnectionFactoryjedisConnectionFactory=newJedisConnectionFactory();
jedisConnectionFactory.setHostName(host4);
jedisConnectionFactory.setPort(port4);
jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
jedisConnectionFactory.afterPropertiesSet();
container.setConnectionFactory(jedisConnectionFactory);
returncontainer;
}
@Bean
RedisMessageListenerContainerredisContainer5(){
finalRedisMessageListenerContainercontainer=newRedisMessageListenerContainer();
JedisConnectionFactoryjedisConnectionFactory=newJedisConnectionFactory();
jedisConnectionFactory.setHostName(host5);
jedisConnectionFactory.setPort(port5);
jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
jedisConnectionFactory.afterPropertiesSet();
container.setConnectionFactory(jedisConnectionFactory);
returncontainer;
}
@Bean
RedisMessageListenerContainerredisContainer6(){
finalRedisMessageListenerContainercontainer=newRedisMessageListenerContainer();
JedisConnectionFactoryjedisConnectionFactory=newJedisConnectionFactory();
jedisConnectionFactory.setHostName(host6);
jedisConnectionFactory.setPort(port6);
jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
jedisConnectionFactory.afterPropertiesSet();
container.setConnectionFactory(jedisConnectionFactory);
returncontainer;
}
@Bean
RedisKeyExpirationListenerredisKeyExpirationListener1(){
returnnewRedisKeyExpirationListener(redisContainer1());
}
@Bean
RedisKeyExpirationListenerredisKeyExpirationListener2(){
returnnewRedisKeyExpirationListener(redisContainer2());
}
@Bean
RedisKeyExpirationListenerredisKeyExpirationListener3(){
returnnewRedisKeyExpirationListener(redisContainer3());
}
@Bean
RedisKeyExpirationListenerredisKeyExpirationListener4(){
returnnewRedisKeyExpirationListener(redisContainer4());
}
@Bean
RedisKeyExpirationListenerredisKeyExpirationListener5(){
returnnewRedisKeyExpirationListener(redisContainer5());
}
@Bean
RedisKeyExpirationListenerredisKeyExpirationListener6(){
returnnewRedisKeyExpirationListener(redisContainer6());
}
}
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.data.redis.connection.Message;
importorg.springframework.data.redis.listener.KeyExpirationEventMessageListener;
importorg.springframework.data.redis.listener.RedisMessageListenerContainer;
importjava.util.Date;
/**
*@Authorxiabing5
*@Create2019/9/49:47
*@Descredis过期监听
**/
publicclassRedisKeyExpirationListenerextendsKeyExpirationEventMessageListener{
@Autowired
RedisUtilredisUtil;
@Autowired
LoginUserStatisticsMapperloginUserStatisticsMapper;
publicRedisKeyExpirationListener(RedisMessageListenerContainerlistenerContainer){
super(listenerContainer);
}
@Override
publicvoidonMessage(Messagemessage,byte[]pattern){
//用户做自己的业务处理即可,message.toString()可以获取失效的key
Stringmesg=message.toString();
}
}
3.Redis防止过期key重复监听
对于项目集群情况下,部署多个服务后,容易出现redis过期被多个服务同时监听到,从而执行相同的业务逻辑,这不是我们期望的。单机部署下方法的同步可以采用synchronize关键字。但集群下,就得采用分布式锁。在需要加锁的地方,只要加锁和解锁即可。此处正好写到Redis,那就贴一个自己用的redis分布式锁。
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.stereotype.Component;
importredis.clients.jedis.Jedis;
importjava.util.Collections;
importjava.util.UUID;
/**
*@Authorxiabing5
*@Create2019/9/615:54
*@Descredis分布式锁
**/
@Component
publicclassRedisLock{
@Autowired
Jedisjedis;
privatestaticfinalStringSET_IF_NOT_EXIST="NX";//NX表示如果不存在key就设置value
privatestaticfinalStringSET_WITH_EXPIRE_TIME="PX";//PX表示毫秒
//加锁
publicStringtryLock(Stringkey,LongacquireTimeout){
//生成随机value
StringidentifierValue=UUID.randomUUID().toString();
//设置超时时间
LongendTime=System.currentTimeMillis()+acquireTimeout;
//循环获取锁
while(System.currentTimeMillis()
4.总结
自己实现的一个小demo,废话比较少。小白自己写的配置类,理解有问题请留言!自己实现的方案感觉不妥,只是基本完成需求,还得继续研究。
以上所述是小编给大家介绍的Redis集群下过期key监听的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!