spring - 过期key触发事件-Spring data Redis

标签 spring redis spring-data spring-data-redis

我正在尝试使用 spring data redis 设置一个 key 过期事件处理程序,但无法使其工作。我做了一些研究,但没有达到预期的结果。不知道我错过了什么。当 redis 缓存上的键过期时,我想记录一条消息。

@Configuration
@EnableRedisRepositories
public class RedisConfig {

    @Bean 
    StringRedisTemplate stringRedisTemplate(){
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(jedisConnectionFactory());
        return stringRedisTemplate;
    }

    @Bean
    RedisMessageListenerContainer redisContainer() {
        RedisMessageListenerContainer container 
          = new RedisMessageListenerContainer(); 
        container.setConnectionFactory(jedisConnectionFactory()); 
        container.addMessageListener(messageListener(), topic()); 
        return container; 
    }

    @Bean
    MessageListenerAdapter messageListener() { 
        return new MessageListenerAdapter(new RedisMessageSubscriber());
    }

    @Bean
    MessagePublisher redisPublisher() { 
        return new RedisMessagePublisher();
    }

    @Bean
    ChannelTopic topic() {
        return new ChannelTopic("messageQueue");
    }
}


public interface MessagePublisher {
    void publish(String message);
}

public class RedisMessagePublisher implements MessagePublisher {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private ChannelTopic topic;

    public void publish(String message) {
        stringRedisTemplate.convertAndSend(topic.getTopic(), message);
    }
}

@Service
public class RedisMessageSubscriber implements MessageListener {

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

    public static List<String> messageList = new ArrayList<String>();

    @Override
    public void onMessage(Message message, byte[] pattern) {
        messageList.add(message.toString());
    }

}

有人可以帮忙吗? 谢谢

最佳答案

首先,需要在redis中为过期事件启用键空间通知。 默认情况下,键空间事件通知被禁用,因为虽然不是很明智,但该功能会占用一些 CPU 资源。使用 redis.conf 的 notify-keyspace-events 或通过 CONFIG SET 启用通知。

notify-keyspace-events "Ex"

当您使用完 Redis 后,您需要使用模式主题 "__keyevent@*__:expired" 配置您的消息监听器。这是代码示例。

监听类:

@Component
public class ExpirationListener implements MessageListener {
    private static final Logger logger = LoggerFactory.getLogger(ExpirationListener.class);

    @Override
    public void onMessage(Message message, byte[] bytes) {
        String key = new String(message.getBody());
        logger.debug("expired key: {}", key);
    }
}

配置:

@Bean
RedisMessageListenerContainer keyExpirationListenerContainer(RedisConnectionFactory connectionFactory, ExpirationListener expirationListener) {
    RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
    listenerContainer.setConnectionFactory(connectionFactory);
    listenerContainer.addMessageListener(expirationListener, new PatternTopic("__keyevent@*__:expired"));
    listenerContainer.setErrorHandler(e -> logger.error("There was an error in redis key expiration listener container", e));
    return listenerContainer;
}

关于spring - 过期key触发事件-Spring data Redis,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49563612/

相关文章:

java - 自定义身份验证过滤器 Spring Security 3.2

redis - 带有哨兵的 Redis 在脑裂后的表现如何?

java - 我们能否保护域模型免受 JSON 请求的影响而不创建 DTO 对象?

java - 如何在 Apache Beam 中使用流输入 PCollection 请求 Redis 服务器?

mongodb - Spring data 和 mongoDB - 继承和@DBRef

java - PagingAndSortingRepository 方法在与 spring data jdbc 一起使用时抛出错误

java - 基于哈希的分区

java - 如何在 REST API 中以 POST 方法发送日期

java - 在 Spring Data 上选择字段

redis - 配置文件中的 "default"是什么(在本例中为 redis-server)