redis 永不过期 java_redis key过期事件实现过期提醒

本文介绍了如何开启Redis的键空间通知并利用Java进行配置,以便在Redis键过期时接收到通知。通过配置Redis配置文件启用键事件通知,并在Java应用中创建RedisTemplate和CacheManager,结合监听器监听过期事件,实现过期提醒功能。
摘要由CSDN通过智能技术生成

redis默认关闭,不建议开启。本文提供参考。键空间通知通常是不启用的,因为这个过程会产生额外消耗。

1、开启redis配置

#

# notify-keyspace-events Ex

#

# By default all notifications are disabled because most users don't need

# this feature and the feature has some overhead. Note that if you don't

# specify at least one of K or E, no events will be delivered.

notify-keyspace-events "Ex"

字符

发送通知

K

键空间通知,所有通知以 keyspace@ 为前缀,针对Key

E

键事件通知,所有通知以 keyevent@ 为前缀,针对event

g

DEL 、 EXPIRE 、 RENAME 等类型无关的通用命令的通知

$

字符串命令的通知

l

列表命令的通知

s

集合命令的通知

h

哈希命令的通知

z

有序集合命令的通知

x

过期事件:每当有过期键被删除时发送

e

驱逐(evict)事件:每当有键因为 maxmemory 政策而被删除时发送

A

参数 g$lshzxe 的别名,相当于是All

输入的参数中至少要有一个 K 或者 E , 否则的话, 不管其余的参数是什么, 都不会有任何通知被分发。上表中斜体的部分为通用的操作或者事件,而黑体则表示特定数据类型的操作。例如,“Kx”表示想监控某个Key的失效事件。

2、java实现

2.1 pom配置

spring boot2的配置

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-data-redis

org.apache.commons

commons-pool2

2.2 配置

import java.lang.reflect.Method;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cache.CacheManager;

import org.springframework.cache.annotation.CachingConfigurerSupport;

import org.springframework.cache.annotation.EnableCaching;

import org.springframework.cache.interceptor.KeyGenerator;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.redis.cache.RedisCacheManager;

import org.springframework.data.redis.connection.RedisConnectionFactory;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.data.redis.listener.ChannelTopic;

import org.springframework.data.redis.listener.RedisMessageListenerContainer;

import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;

import com.fasterxml.jackson.annotation.PropertyAccessor;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.spring.pro.constant.ChannelConstant;

import com.spring.pro.listener.KeyExpiredListener;

import com.spring.pro.listener.UserMsgListener;

/**

* 缓存管理(注解用)

* @ClassName: CacheService

* @Description:

* @author ybw

* @date 2017年4月20日 下午5:44:52

*/

@Configuration

@EnableCaching // 启动缓存

public class CacheConfig extends CachingConfigurerSupport {

/**

* 生成key的策略

* @return

*/

@Bean

public KeyGenerator keyGenerator() {

return new KeyGenerator() {

@Override

public Object generate(Object target, Method method, Object... params) {

StringBuilder sb = new StringBuilder();

sb.append(target.getClass().getName());

sb.append(method.getName());

for (Object obj : params) {

sb.append(obj.toString());

}

return sb.toString();

}

};

}

/**

* 管理缓存

* @param redisTemplate

* @return

*/

@Bean

public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {

RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder

.fromConnectionFactory(redisConnectionFactory);

return builder.build();

}

/**

* RedisTemplate配置

* @param factory

* @return

*/

@Bean

public RedisTemplate redisTemplate(RedisConnectionFactory factory) {

StringRedisTemplate template = new StringRedisTemplate(factory);

// 使用Jackson库将对象序列化为JSON字符串

Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(

Object.class);

ObjectMapper om = new ObjectMapper();

om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

jackson2JsonRedisSerializer.setObjectMapper(om);

template.setValueSerializer(jackson2JsonRedisSerializer);

template.afterPropertiesSet();

return template;

}

// --------------------------pub/sub-----------------------------------------

@Resource

private KeyExpiredListener keyExpiredListener;

@Bean

public ChannelTopic expiredTopic() {

return new ChannelTopic(ChannelConstant.expired);

}

@Bean

public RedisMessageListenerContainer redisMessageListenerContainer(

@Autowired RedisConnectionFactory redisConnectionFactory) {

RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();

redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);

redisMessageListenerContainer.addMessageListener(keyExpiredListener, expiredTopic());

return redisMessageListenerContainer;

}

// --------------------------pub/sub end------------------------------------------

}

3、监听

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

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

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

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.stereotype.Component;

/**

* @Title: KeyExpiredListener.java

* @Package com.spring.pro.listener

* @Description:

* @author ybwei

* @date 2018年8月13日 下午3:54:41

* @version V1.0

*/

@Component

public class KeyExpiredListener implements MessageListener {

private final static Logger LOG = LoggerFactory.getLogger(UserMsgListener.class);

@Autowired

private RedisTemplate, ?> redisTemplate;

@Override

public void onMessage(Message message, byte[] pattern) {

System.out.println("onPMessage pattern " + pattern + " " + " " + message);

String channel = new String(message.getChannel());

String str = (String) redisTemplate.getValueSerializer().deserialize(message.getBody());

LOG.info("received message channel {}, body is {}.", channel, str);

}

}

4、测试

set aa bb

expire aa 2 #设置失效时间2秒

aa失效后,即可得到通知。

转载至链接:https://my.oschina.net/u/182501/blog/1927210

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值