redis監聽過期key時間

說明
redis key過期監聽通知一定要 開啓key過期通知功能。

 事件通過 Redis 的訂閱與發佈功能(pub/sub)來進行分發,故需要訂閱 __keyevent@0__:expired 這個topic通道

解釋:keyevent@2:expired
__keyevent 必須以此開頭;
@2 表示監聽第二個數據庫;
:expired 表示過期事件

1、redis 開啓key過期通知

1、修改 redis.conf 文件 ,編輯/etc/redis/redis.conf文件,添加或啓用以下內容(過期通知):
配置詳解:

 

字符 發送通知
K 鍵空間通知,所有通知以 keyspace@ 爲前綴,針對Key
E 鍵事件通知,所有通知以 keyevent@ 爲前綴,針對event
g DEL 、 EXPIRE 、 RENAME 等類型無關的通用命令的通知
$ 字符串命令的通知
l 列表命令的通知
s 集合命令的通知
h 哈希命令的通知
z 有序集合命令的通知
x 過期事件:每當有過期鍵被刪除時發送
e 驅逐(evict)事件:每當有鍵因爲 maxmemory 政策而被刪除時發送
A 參數 g$lshzxe 的別名,相當於是All

將  notify-keyspace-events "" 改爲  notify-keyspace-events "Ex"

然後、重啓redis , 即可測試失效事件的觸發, 監聽獲取的值爲 key

2、或者登陸redis-cli之後,輸入以下命令:
config set notify-keyspace-events Ex

需要的jar包

                <dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>2.9.0</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-redis</artifactId>
			<version>1.8.4.RELEASE</version>
		</dependency>

配置文件

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       ......
       default-lazy-init="false">

    <context:property-placeholder location="classpath:redis.properties"
                                  ignore-unresolvable="true"/>
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="1000"/>
        <property name="minIdle" value="1000"/>
        <property name="maxTotal" value="100"/>
        <property name="testOnBorrow" value="true"/>
        <property name="testOnReturn" value="true"/>
    </bean>

    <bean id="jedisConnectionFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
          p:host-name="127.0.0.1"
          p:port="6379"
          p:pool-config-ref="jedisPoolConfig"
          p:use-pool="true"
          p:database="${redis.database}"/>

    <bean id="RedisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
          p:connection-factory-ref="jedisConnectionFactory"
          p:keySerializer-ref="stringRedisSerializer"
          p:valueSerializer-ref="JdkSerializationRedisSerializer"/>

    <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    <bean id="JdkSerializationRedisSerializer"
          class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>

    <bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter">
        <constructor-arg>
            <bean class="com.mmall.concurrency.listener.RedisKeyExpiredListener"/>
        </constructor-arg>
    </bean>
    <bean id="redisContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer">
        <property name="connectionFactory" ref="jedisConnectionFactory" />
        <property name="messageListeners">
            <map>
                <entry key-ref="messageListener">
                    <list>
<!--                        <bean class="org.springframework.data.redis.listener.ChannelTopic">-->
<!--                            <constructor-arg value="__keyevent@1__:expired" />-->
<!--                        </bean>-->
<!--                        <bean class="org.springframework.data.redis.listener.PatternTopic">-->
<!--                            <constructor-arg value="*" />-->
<!--                        </bean>-->
<!--                        <bean class="org.springframework.data.redis.listener.PatternTopic">-->
<!--                            <constructor-arg value="'__key*__:*" />-->
<!--                        </bean>-->
                        <bean class="org.springframework.data.redis.listener.ChannelTopic">
                            <constructor-arg value="__keyevent@2__:expired"/>
                        </bean>
                    </list>
                </entry>
            </map>
        </property>
    </bean>
</beans>

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;


/**
 * redis監聽
 * 監聽類需要實現MessageListener,監聽到redis key過期的時候會自動執行到onMessage方法
 * @version 1.0
 */
@Slf4j
public class RedisKeyExpiredListener implements MessageListener {

    private static final String FAIL_KEY = "fail:key";

    @Autowired
    private TestService testService;

    @Override
    public void onMessage(Message message, byte[] bytes) {
        String expiredKey = message.toString();// 獲取失效的key
        log.info("=========>失效的key:{}", expiredKey);
        if (expiredKey.startsWith(FAIL_KEY )) {
            // 進行相應的業務處理....
        }
    }
}

上面就可以完成監聽的功能!!!!

 

上面的代碼還可以改寫成下面的形式

@Component(value ="SERVICE_NAME")
@Slf4j
public class RedisKeyExpiredListener implements MessageListener {

    private static final String FAIL_KEY = "fail:key";

    @Autowired
    private TestService testService;

    @Override
    public void onMessage(Message message, byte[] bytes) {
        String expiredKey = message.toString();// 獲取失效的key
        log.info("=========>失效的key:{}", expiredKey);
        if (expiredKey.startsWith(FAIL_KEY )) {
            // 進行相應的業務處理....
        }
    }
}



import com.mmall.concurrency.listener.RedisKeyExpiredListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

/**
 * redis監聽容器
 * @author 12706
 */
@Configuration
public class RedisConfig {

    @Autowired
    @Qualifier(value = "SERVICE_NAME")//指定的是自己寫的RedisMessageListener
    private RedisKeyExpiredListener redisKeyExpiredListener;

    @Autowired
    private RedisTemplate redisTemplate;

    @Bean
    public RedisMessageListenerContainer container(MessageListenerAdapter listenerAdapter) {

        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(redisTemplate.getConnectionFactory());
        container.addMessageListener(listenerAdapter, new PatternTopic("__keyevent@0__:expired"));
        //這裏是監聽redis第一個庫裏面key的過期
        return container;
    }

    @Bean
    public MessageListenerAdapter listenerAdapter() {
        return new MessageListenerAdapter(redisKeyExpiredListener);
    }
}

 

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