• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    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监听的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
    如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

    您可能感兴趣的文章:
    • 基于docker搭建redis集群的方法
    • Docker 部署单机版 Pulsar 和集群架构 Redis(开发神器)的方法
    • Redis Cluster集群数据分片机制原理
    • springcloud微服务基于redis集群的单点登录实现解析
    • springboot整合redis集群过程解析
    • Java调用Redis集群代码及问题解决
    • Linux(Centos7)下redis5集群搭建和使用说明详解
    • 基于docker搭建redis-sentinel集群的方法示例
    • 详细分析Redis集群故障
    • 比较几种Redis集群方案
    上一篇:详解redis desktop manager安装及连接方式
    下一篇:利用Redis如何实现自动补全功能
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Redis集群下过期key监听的实现代码 Redis,集群,下,过期,key,监听,