redis缓存过期监听工具类-监听过期缓存并删除

1. 事件通过 Redis 的订阅与发布功能(pub/sub)来进行分发,故需要订

阅 __keyevent@0__:expired 通道

0表示db0 根据自己的dbindex选择合适的数字

2. 修改 redis.conf 文件 

执行客户端命令 config set notify-keyspace-events Ex 

# K    键空间通知,以__keyspace@__为前缀
# E    键事件通知,以__keysevent@__为前缀
# g    del , expipre , rename 等类型无关的通用命令的通知, ...
# $    String命令
# l    List命令
# s    Set命令
# h    Hash命令
# z    有序集合命令
# x    过期事件(每次key过期时生成)
# e    驱逐事件(当key在内存满了被清除时生成)
# A    g$lshzxe的别名,因此”AKE”意味着所有的事件
 
  
package com.zjht.solar.listenter;

import com.zjht.solar.act.constant.TransTypeString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.data.redis.connection.jedis.JedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * 缓存监听。
 * Created by gaosiling on 2017/11/24。
 */
public class KeyExpiredListener2 extends JedisPubSub
    implements ApplicationListener {

    private static final Logger logger = LoggerFactory.getLogger(KeyExpiredListener2.class);

    @Autowired
    private JedisConnectionFactory jedisConnectionFactory;

    @Autowired
    private RedisTemplate redisTemplate;


    // 初始化订阅时候的处理
    @Override
    public void onPSubscribe(String pattern, int subscribedChannels) {
    }

    // 取得订阅的消息后的处理
    @Override
    public void onPMessage(String pattern, String channel, String message) {
        try {
            logger.info("缓存过期处理缓存key=============" + message);
            if (message.indexOf(TransTypeString.ACTIVITYCODE) == -1) {
                return;
            }
            String key = message.substring("activityCode_".length());
            logger.info("缓存过期处理" + key);
            //删除过期的缓存
            deleteKey(key);
        } catch (Exception ex) {
            logger.info("活动解析异常" + ex);
        }

    }

    //应用启动时只调用一次,并创建一个线程处理redis缓存过期
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。
                logger.info("启动新线程调用redis缓存监听");
                JedisConnection jedisConnection =
                    (JedisConnection) jedisConnectionFactory.getConnection();
                Jedis jedis = jedisConnection.getNativeConnection();
                jedis.psubscribe(new KeyExpiredListener2(), "__key*__:*");
            }
        }).start();

    }


    public void deleteKey(String key) {
        List redisActivity = new ArrayList<>();
        if (redisActivity == null || redisActivity.size() == 0) {
            return;
        }
        Iterator it = redisActivity.iterator();
        while (it.hasNext()) {
            String s = it.next();
            if (s.equals(key)) {
                it.remove();
            }
        }
        setActivity(key, redisActivity);
    }

    private void setActivity(String key, List list) {
        delete(key);
        if (list.size() == 0) {
            return;
        }
        redisTemplate.opsForList().leftPushAll(key, list);
        redisTemplate.expireAt(key, new Date());
        JedisConnection jedisConnection =
            (JedisConnection) jedisConnectionFactory.getConnection();
        Jedis jedis = jedisConnection.getNativeConnection();
        for (String vo : list) {
            try {
                long time = new Date().getTime() - System.currentTimeMillis();
                if (time < 0) {
                    time = 0;
                }
                jedis.setex(TransTypeString.ACTIVITYCODE + new Date(),
                            (int) (time / 1000), "nx");
            } catch (Exception ex) {
                logger.info("保存活动缓存监听失败" + key + ex);
            }
        }
        jedisConnection.close();

    }

    /**
     * 删除活动。
     *
     * @param key key。
     */
    private void delete(String key) {
        redisTemplate.delete(key);
    }
}

 
 

你可能感兴趣的:(redis缓存过期监听工具类-监听过期缓存并删除)