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监听的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!