redis事件通知(notify-keyspace-events Ex)

Keyspace 通知使客户端可以通过订阅频道接收那些以某种方式改动了 Redis 数据集的事件(触发某些事件后可以向指定的频道发送通知),该功能需 Redis 版本大于 2.8。

问题:

  • 设置了生存时间的Key,在过期时能不能有所提示?
  • 如果能对过期key一个监听,如何对过期key进行一个回调处理?

Key过期事件的Redis配置

notify-keyspace-events Ex

notify-keyspace-events 的参数为 “Ex”。x 代表了过期事件

ok  重启redis

下面请看代码演示

pom.XML

        
            org.springframework.boot
            spring-boot-starter-data-redis
            2.1.9.RELEASE
        
        
            com.fasterxml.jackson.core
            jackson-core
            2.10.1
        
        
            com.fasterxml.jackson.core
            jackson-databind
            2.10.1
        

application.yml

  redis:
    host: localhost
    port: 6379
   #password: xxx
    lettuce:
      pool:
        max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
        max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-idle: 8 # 连接池中的最大空闲连接
        min-idle: 0 # 连接池中的最小空闲连接
    timeout: 3000 # 连接超时时间(毫秒)
RedisConfig.class
package com.example.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
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.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;


@Configuration
@EnableCaching
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig extends CachingConfigurerSupport {
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... objects) {
                StringBuffer sb = new StringBuffer();
                sb.append(o.getClass().getName()).append(method.getName());
                for (Object object : objects) {
                    sb.append(object.toString());
                }
                System.out.println(sb.toString());
                return sb.toString();
            }
        };
    }

    @Bean
    public CacheManager cacheManager(LettuceConnectionFactory lettuceConnectionFactory) {
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(json()));
        return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(lettuceConnectionFactory))
                .cacheDefaults(redisCacheConfiguration).build();
        //return RedisCacheManager.create(lettuceConnectionFactory);
    }

    @Bean
    public RedisTemplate redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate();
        Jackson2JsonRedisSerializer jsonSerializer = json();
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(jsonSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(jsonSerializer);
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        return redisTemplate;
    }

    private Jackson2JsonRedisSerializer json() {
        Jackson2JsonRedisSerializer jsonSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
        jsonSerializer.setObjectMapper(om);
        return jsonSerializer;
    }

    @Bean
    RedisMessageListenerContainer container(LettuceConnectionFactory connectionFactory) {

        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }
}

RedisKeyExpirationListener.class
package com.example.config;

import lombok.extern.slf4j.Slf4j;
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;

@Slf4j
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }
//    @Resource
//    SeatService seatService;
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String expiredKey = message.toString();
        if(expiredKey.equals("keyTest")){
            log.info(expiredKey + "----动作触发");
//            seatService.updateToFreeSeat("1");
        }
        try {
            //业务处理
        } catch (Exception e) {
            log.error("key 过期通知处理异常,{}", e);
        }

    }

}
ProductController.class
import com.example.config.CIpProperties;
import com.example.config.NameProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.concurrent.TimeUnit;

@Controller
public class ProductController {
    @Autowired
private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private CIpProperties cIpProperties;
    @Autowired
    private NameProperties nameProperties;
    @RequestMapping
    @ResponseBody
    public String hello(){
        return "success";
    }

    @RequestMapping("/test")
    @ResponseBody
    public Object test(){
        stringRedisTemplate.opsForValue().set("keyTest","1",10, TimeUnit.SECONDS);
        return null;
    }
}

redis事件通知(notify-keyspace-events Ex)_第1张图片

你可能感兴趣的:(reids,spring)