【问题标题】:Expired key trigger event - Spring data Redis过期键触发事件 - Spring data Redis
【发布时间】:2018-09-08 20:33:49
【问题描述】:

我正在尝试使用 spring data redis 设置密钥到期事件处理程序,但无法使其工作。我做了一些研究,但没有产生预期的结果。不知道我错过了什么。当 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());
    }

}

有人可以帮忙吗? 谢谢

【问题讨论】:

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


    【解决方案1】:

    首先需要在redis中开启expire事件的keyspace通知。 默认情况下,键空间事件通知被禁用,因为虽然不是很明智,但该功能使用了一些 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;
    }
    

    【讨论】:

    • 是否可以获取消息本身,而不仅仅是key?
    • @EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP) 启用键空间事件,而无需弄乱 Redis 控制台或配置文件。
    猜你喜欢
    • 1970-01-01
    • 2020-09-26
    • 2016-04-25
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    • 2021-09-30
    • 2021-09-13
    • 2014-10-06
    相关资源
    最近更新 更多