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了。

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