redis订阅实现key值失效时,触发程序

1.项目中需要在redis中存放时效的key,当失效时触发事件
2.项目启动时监听redis中0索引数据库中所有失效key

@Component
public class SocketServer {
 @Autowired
 private MyPubSubListener myPubSubListener;
 @PostConstruct
 public void init() {
  logger.info("监听redis");
  String[] channels = new String[1];
  channels[0] = "__keyevent@0__:expired";
  final RedisSubcribeClient client = new RedisSubcribeClient("statusWatch", myPubSubListener, channels);
  new Thread(new Runnable() {
   @Override
   public void run() {
    client.subscribe();
   }
  }).start();
 }
}

3.key失效,执行程序onMessage方法,message为失效的key
我的key是{ip:1234},key是不固定值

@Component
public class MyPubSubListener extends JedisPubSub {
 private Logger log = LoggerFactory.getLogger(this.getClass());
 @Autowired
 private RedisUtils redis;
 @Override
 public void onMessage(String channel, String message) {
  log.info("当前频道:" + channel);
  log.info("接收消息:" + message);
  if(message.contains("{")&&message.contains("}")) {
   try {
    JSONObject obj = JSONObject.parseObject(message);
    String ip = obj.getString("socket");
    SocketServer.map.remove(ip);
   }catch(Exception e) {
    e.printStackTrace();
   }
  }
 }
 @Override
 public void onSubscribe(String channel, int subscribedChannels) {
  log.info("订阅频道" + channel);
 }
 @Override
 public void onUnsubscribe(String channel, int subscribedChannels) {
  log.info("取消订阅频道" + channel);
 }
 /**
  * 全部取消订阅
  */
 @Override
 public void unsubscribe() {
  // TODO
 }
}

4.订阅redis事件

public class RedisSubcribeClient {
 private Jedis jedis;
 private String[] channels;
 private String name;
 private JedisPubSub listener;
 private static final Logger log = Logger.getLogger(RedisSubcribeClient.class);
 public RedisSubcribeClient(String channel) {
  this.jedis = RedisMgr.getJedis();
 }
 public RedisSubcribeClient(String clientName, JedisPubSub listener, String[] channels) {
  if (RedisMgr.getJedis() == null) {
   this.jedis = RedisMgr.getInstance().getJedis();
  } else {
   this.jedis = RedisMgr.getJedis();
  }
  this.channels = channels;
  this.listener = listener;
  this.name = clientName;
 }
 public void subscribe() {
  log.info("client:" + this.name + "\t订阅频道:" + this.channels[0] + "listener:"
    + this.listener.getClass().getName());
  log.info("jedis is null:" + String.valueOf(jedis == null));
  jedis.subscribe(this.listener, this.channels[0]);
 }
 public void cancelSubscribe(String[] channels) {
  log.info("取消订阅,当前client名为:" + this.name);
  this.listener.unsubscribe(channels);
 }
}

5.redis管理类

public class RedisMgr {
 public static RedisMgr redisClientPool = getInstance();
 public static JedisPool jedisPool;
 private String host;
 private int port;
 private String auth;
 private int database;
 public static synchronized RedisMgr getInstance() {
  if (null == redisClientPool) {
   redisClientPool = new RedisMgr();
  }
  return redisClientPool;
 }
 public RedisMgr() {
  if (null == jedisPool) {
   init();
  }
 }
 public String getInfo(){
  StringBuilder sb = new StringBuilder();
  sb.append("host:"+this.host);
  sb.append("port:"+this.port);
  sb.append("database:"+this.database);
  sb.append("auth:"+this.auth);
  return sb.toString();
 }
 /**
  * 初始化jedis连接池
  */
 private void init() {
  JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        //控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取;
        //如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
  jedisPoolConfig.setMaxTotal(500);
  // 最大能够保持空闲状态的对象数
  jedisPoolConfig.setMaxIdle(300);
  // 超时时间
  jedisPoolConfig.setMaxWaitMillis(1000);
  // 在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;
  jedisPoolConfig.setTestOnBorrow(true);
  // 在还会给pool时,是否提前进行validate操作
  jedisPoolConfig.setTestOnReturn(true);
  Properties property = new Properties();
  String propertyPath = this.getClass().getClassLoader().getResource("config.properties").getPath();
  try {
   property.load(new FileInputStream(new File(propertyPath)));
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
  String host = property.getProperty("redis.host");// "localhost";
  int port = Integer.parseInt(property.getProperty("redis.port"));// 6379;
  int database = Integer.parseInt(property.getProperty("redis.database"));// 6379;
  int timeout = Integer.parseInt(property.getProperty("redis.timeout"));// 60000;
  this.host = host;
  this.port = port;
  this.database = database;
  String auth = property.getProperty("redis.password");//访问密码
  this.auth = auth;
  if(StringUtils.isNotBlank(auth)){
   jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, auth);
  }else{
   jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout);
  }
 }
    /**
     * 获取Jedis实例
     * 默认使用数据库0
     * @return
     */
    public synchronized static Jedis getJedis() {
        try {
            if (jedisPool != null) {
                Jedis resource = jedisPool.getResource();
                return resource;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 获取Jedis实例并指定数据库
     * @param db_index 数据库索引
     * @return
     */
    public synchronized static Jedis getJedis(int db_index) {
        try {
            if (jedisPool != null) {
                Jedis resource = jedisPool.getResource();
                resource.select(db_index);
                return resource;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值