springBoot监听redis失效key事件

序:

      这次遇到的场景是需要对redis的失效key做比对判断,增加电业务逻辑。

      废话不多说,直接说重点,我也赶着回家呢。

      redis配置文件修改,我是win系统。这个是对redis版本有要求的,所以先查看版本信息。

      查看redis版本信息,redis安装目录下,黑框框(你懂的)下运行redis-cli.exe,然后再输入info

这个实际上是高版本的redis的消息队列的一种使用。redis版本要求2.8.0以上,我这里装的是3.2.100

redis配置文件修改,找到redis.windows.conf文件,用记事本类工具打开。

重启redis服务,注意要带配置文件哦,很多人起服务不带这个redis配置文件,所以每次重启里面的key都丢失了。

验证是否会有监听

还是在刚刚输入info命令的黑框框继续输入 psubscribe "__keyevent@*:expired",回车。你会看到

然后,配合redis Desktop Manager看效果,打开这个工具,连接上redis后,打开命令行

看到效果没,我在命令行输入用命令设置一个3秒超时的key value,然后黑框框3s后就有反应了。

上面讲的基本是原理,下面上java代码

springBoot增加一个配置,上次说到过redis增加配置,真是简单,方便的不要不要的,直接在config包下增加一个配置类RedisListenerConfig类,代码如下:

package com.filler.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

import com.filler.listenner.RedisExpiredListener;

@Configuration
public class RedisListenerConfig {
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {

        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        //下面这种方式是灵活配置,针对每个库的失效key做处理
        //container.addMessageListener(new RedisExpiredListener(), new PatternTopic("__keyevent@0__:expired"));
        return container;
    }
}
 

然后我建了一个listenner的包,在下面增加一个监听类:

package com.filler.listenner;

import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

/**
 * redis失效key监听
 * 
 * @author 郑文
 *
 */
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    /**
     * redis失效key事件处理
     * @param message
     * @param pattern
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        // message.toString()可以获取失效的key
        String expiredKey = message.toString();
        System.out.println("-------------------");
        System.out.println("失效key:"+expiredKey);
    }
}
还有一个监听类,是配合上面的配置文件注释的部分的,可以灵活配置,配置监听不同的库,redis有16个库。

package com.filler.listenner;

import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;

public class RedisExpiredListener implements MessageListener {
    @Override
    public void onMessage(Message message, byte[] bytes) {
        byte[] body = message.getBody();// 建议使用: valueSerializer
        byte[] channel = message.getChannel();
        System.out.print("onMessage >> " );
        System.out.println(String.format("channel: %s, body: %s, bytes: %s"
                ,new String(channel), new String(body), new String(bytes)));
    }

}

ok了,代码写完了,看看效果,还是用redis Desktop Manager配合java代码


看到效果了吧。然后你就可以在你的监听类里判断失效key的特征,写自己的业务逻辑。唯一遗憾的是不能难道value,也能够理解,实际就是redis删除失效key做了一个通知主题被java感知了。以后有个redis失效key的前置事件就好了。现在变相的处理方式,可以约定业务存2个key,一个有失效时间,一个没有,比如存win这个key时,还存一个win_val可以,在失效监听里自己再去取win_val的value消费,消费完成后删除这个win_val的key。

好了就到这里了,剩下的业务逻辑就可以fly your self了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章