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
import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.serializer.StringRedisSerializer; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPoolConfig; import java.util.Arrays; /** * @Author xiabing5 * @Create 2019/8/6 14:46 * @Desc 监听redis中Key过期事件 **/ @Configuration public class RedisListenerConfig { @Value("${redis.host1}") private String host1; @Value("${redis.host2}") private String host2; @Value("${redis.host3}") private String host3; @Value("${redis.host4}") private String host4; @Value("${redis.host5}") private String host5; @Value("${redis.host6}") private String host6; @Value("${redis.port1}") private int port1; @Value("${redis.port2}") private int port2; @Value("${redis.port3}") private int port3; @Value("${redis.port4}") private int port4; @Value("${redis.port5}") private int port5; @Value("${redis.port6}") private int port6; @Bean JedisPoolConfig jedisPoolConfig(){ JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxIdle(100); jedisPoolConfig.setMaxWaitMillis(1000); return jedisPoolConfig; } // redis-cluster不支持key过期监听,建立多个连接,对每个redis节点进行监听 @Bean RedisMessageListenerContainer redisContainer1() { final RedisMessageListenerContainer container = new RedisMessageListenerContainer(); JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(); jedisConnectionFactory.setHostName(host1); jedisConnectionFactory.setPort(port1); jedisConnectionFactory.setPoolConfig(jedisPoolConfig()); jedisConnectionFactory.afterPropertiesSet(); container.setConnectionFactory(jedisConnectionFactory); return container; } @Bean RedisMessageListenerContainer redisContainer2() { final RedisMessageListenerContainer container = new RedisMessageListenerContainer(); JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(); jedisConnectionFactory.setHostName(host2); jedisConnectionFactory.setPort(port2); jedisConnectionFactory.setPoolConfig(jedisPoolConfig()); jedisConnectionFactory.afterPropertiesSet(); container.setConnectionFactory(jedisConnectionFactory); return container; } @Bean RedisMessageListenerContainer redisContainer3() { final RedisMessageListenerContainer container = new RedisMessageListenerContainer(); JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(); jedisConnectionFactory.setHostName(host3); jedisConnectionFactory.setPort(port3); jedisConnectionFactory.setPoolConfig(jedisPoolConfig()); jedisConnectionFactory.afterPropertiesSet(); container.setConnectionFactory(jedisConnectionFactory); return container; } @Bean RedisMessageListenerContainer redisContainer4() { final RedisMessageListenerContainer container = new RedisMessageListenerContainer(); JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(); jedisConnectionFactory.setHostName(host4); jedisConnectionFactory.setPort(port4); jedisConnectionFactory.setPoolConfig(jedisPoolConfig()); jedisConnectionFactory.afterPropertiesSet(); container.setConnectionFactory(jedisConnectionFactory); return container; } @Bean RedisMessageListenerContainer redisContainer5() { final RedisMessageListenerContainer container = new RedisMessageListenerContainer(); JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(); jedisConnectionFactory.setHostName(host5); jedisConnectionFactory.setPort(port5); jedisConnectionFactory.setPoolConfig(jedisPoolConfig()); jedisConnectionFactory.afterPropertiesSet(); container.setConnectionFactory(jedisConnectionFactory); return container; } @Bean RedisMessageListenerContainer redisContainer6() { final RedisMessageListenerContainer container = new RedisMessageListenerContainer(); JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(); jedisConnectionFactory.setHostName(host6); jedisConnectionFactory.setPort(port6); jedisConnectionFactory.setPoolConfig(jedisPoolConfig()); jedisConnectionFactory.afterPropertiesSet(); container.setConnectionFactory(jedisConnectionFactory); return container; } @Bean RedisKeyExpirationListener redisKeyExpirationListener1() { return new RedisKeyExpirationListener(redisContainer1()); } @Bean RedisKeyExpirationListener redisKeyExpirationListener2() { return new RedisKeyExpirationListener(redisContainer2()); } @Bean RedisKeyExpirationListener redisKeyExpirationListener3() { return new RedisKeyExpirationListener(redisContainer3()); } @Bean RedisKeyExpirationListener redisKeyExpirationListener4() { return new RedisKeyExpirationListener(redisContainer4()); } @Bean RedisKeyExpirationListener redisKeyExpirationListener5() { return new RedisKeyExpirationListener(redisContainer5()); } @Bean RedisKeyExpirationListener redisKeyExpirationListener6() { return new RedisKeyExpirationListener(redisContainer6()); } }
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import java.util.Date; /** * @Author xiabing5 * @Create 2019/9/4 9:47 * @Desc redis过期监听 **/ public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener { @Autowired RedisUtil redisUtil; @Autowired LoginUserStatisticsMapper loginUserStatisticsMapper; public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Override public void onMessage(Message message, byte[] pattern) { // 用户做自己的业务处理即可,message.toString()可以获取失效的key String mesg = message.toString(); } }
3. Redis防止过期key重复监听
对于项目集群情况下,部署多个服务后,容易出现redis过期被多个服务同时监听到,从而执行相同的业务逻辑,这不是我们期望的。单机部署下方法的同步可以采用synchronize关键字。但集群下,就得采用分布式锁。在需要加锁的地方,只要加锁和解锁即可。此处正好写到Redis,那就贴一个自己用的redis分布式锁。
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import redis.clients.jedis.Jedis; import java.util.Collections; import java.util.UUID; /** * @Author xiabing5 * @Create 2019/9/6 15:54 * @Desc redis分布式锁 **/ @Component public class RedisLock { @Autowired Jedis jedis; private static final String SET_IF_NOT_EXIST = "NX"; // NX表示如果不存在key就设置value private static final String SET_WITH_EXPIRE_TIME = "PX"; // PX表示毫秒 // 加锁 public String tryLock(String key,Long acquireTimeout) { // 生成随机value String identifierValue = UUID.randomUUID().toString(); // 设置超时时间 Long endTime = System.currentTimeMillis() + acquireTimeout; // 循环获取锁 while (System.currentTimeMillis() < endTime) { String result = jedis.set(key,identifierValue, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, acquireTimeout); if("OK".equals(result)) { return identifierValue; } } return null; } // 解锁 // public void delLock(String key,String identifierValue) { // // 判断是否是同一把锁 // try{ // if(jedis.get(key).equals(identifierValue)){ // // 此处操作非原子性,容易造成释放非自己的锁 // jedis.del(key); // } // }catch(Exception e) { // e.printStackTrace(); // } // } // 使用Lua代码解锁 public void delLock(String key,String identifierValue) { try{ String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; Long result = (Long) jedis.eval(script, Collections.singletonList(key), Collections.singletonList(identifierValue)); if (1 == result) { System.out.println(result+"释放锁成功"); } if (0 == result) { System.out.println(result+"释放锁失败"); } }catch (Exception e) { e.printStackTrace(); } } }
4. 总结
自己实现的一个小demo,废话比较少。小白自己写的配置类,理解有问题请留言!自己实现的方案感觉不妥,只是基本完成需求,还得继续研究。
以上所述是小编给大家介绍的Redis集群下过期key监听的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对猪先飞网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
相关文章
- 这篇文章主要介绍了@CacheEvict 清除多个key的实现方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-13
- 这篇文章主要介绍了Redis连接池配置及初始化实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-29
- 这篇文章主要介绍了详解如何清理redis集群的所有数据,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-18
- 这篇文章主要介绍了vue 监听 Treeselect 选择项的改变操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-01
详解redis desktop manager安装及连接方式
这篇文章主要介绍了redis desktop manager安装及连接方式,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-15Laravel 5.1中定义事件、事件监听器以及触发事件例子
下文我们来看一篇关于Laravel 5.1中定义事件、事件监听器以及触发事件例子,希望能够帮助到各位新手朋友的哦。 这里我们基于之前基于模型+缓存对文章增删改查这篇...2016-11-25- 这篇文章主要介绍了浅谈redis key值内存消耗以及性能影响,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-07
- 这篇文章主要介绍了@Cacheable 拼接key的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-13
- 最近在工作中遇到了一个问题,通过查找相关资料才得知原因是因为返回结果的问题,下面这篇文章主要给大家介绍了关于lua读取redis数据的null判断的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下...2020-06-30
- 这篇文章主要介绍了SpringBoot集成Redis实现消息队列的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-10
- 下面小编就为大家带来一篇js遍历json的key和value的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2017-01-26
redis setIfAbsent和setnx的区别与使用说明
这篇文章主要介绍了redis setIfAbsent和setnx的区别与使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-04- 这篇文章主要介绍了uniapp微信小程序:key失效的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-20
- 这篇文章主要介绍了Redis的Expire与Setex区别说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-15
- 这篇文章主要为大家分享了Bootstrap教程JS插件滚动监听学习笔记,内容很详细,感兴趣的小伙伴们可以参考一下...2016-05-20
详解nginx同一端口监听多个域名和同时监听http与https
这篇文章主要介绍了详解nginx同一端口监听多个域名和同时监听http与https的相关资料,需要的朋友可以参考下...2017-07-06- Redis 是一个开源、高性能的Key-Value数据库,被广泛应用在服务器各种场景中。本文介绍几个查看Redis内存信息的命令,包括常用的info memory、info keyspace、bigkeys等。...2021-01-15
- 本文给大家介绍如何替换json对象中的key,通过实例代码给大家介绍key的替换方法,代码也很简单,需要的朋友参考下吧...2021-06-02
- 这篇文章主要介绍了C#自定义事件监听实现方法,涉及C#事件监听的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
jQuery绑定事件监听bind和移除事件监听unbind用法实例详解
这篇文章主要介绍了jQuery绑定事件监听bind和移除事件监听unbind用法,结合实例形式详细分析了绑定事件监听bind和移除事件监听unbind的具体使用技巧与相关注意事项,需要的朋友可以参考下...2016-01-21