ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

【Redis系列】Spring boot实现监听Redis key失效事件

2021-04-04 04:32:09  阅读:131  来源: 互联网

标签:25 01 container 23 Redis boot --- 2021 key


转:

【Redis系列】Spring boot实现监听Redis key失效事件

talk is cheap, show me the code.

一、开启Redis key过期提醒

  • 方式二:修改配置文件

    redis.conf

    # 默认 notify-keyspace-events ""
    notify-keyspace-events Ex
    
  • 方式二:命令行开启

    CONFIG SET notify-keyspace-events Ex
    CONFIG GET notify-keyspace-events
    

二、notify-keyspace-events

notify-keyspace-events 选项的默认值为空

notify-keyspace-events 的参数可以是以下字符的任意组合, 它指定了服务器该发送哪些类型的通知。

字符 发送的通知
K 键空间通知,所有通知以 keyspace@ 为前缀
E 键事件通知,所有通知以 keyevent@ 为前缀
g DEL 、 EXPIRE 、 RENAME 等类型无关的通用命令的通知
$ 字符串命令的通知
l 列表命令的通知
s 集合命令的通知
h 哈希命令的通知
z 有序集合命令的通知
x 过期事件:每当有过期键被删除时发送
e 驱逐(evict)事件:每当有键因为 maxmemory 政策而被删除时发送
A 参数 g$lshzxe 的别名

三、Coding

  1. 初始化一个Spring Boot项目

  2. pom.xml

    
    		
    			org.springframework.boot
    			spring-boot-starter-data-redis
    		
    		
    			org.projectlombok
    			lombok
    		
    	
    
  3. 定义配置类RedisListenerConfig

    @Configuration
    public class RedisListenerConfig {
    
    	@Bean
    	RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
    		RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    		container.setConnectionFactory(connectionFactory);
    		return container;
    	}
    
    }
    
  4. 定义数据生产类ProviderDataToRedis

    @Slf4j
    @Component
    public class ProviderDataToRedis implements CommandLineRunner {
    
    	@Autowired
    	private StringRedisTemplate stringRedisTemplate;
    
    	@Override
    	public void run(String... args) throws Exception {
    		int[] num = new int[]{1};
    		Random random = new Random();
    		while (true) {
    			int max = random.nextInt(5);
    			IntStream.range(0, max).forEach(n -> stringRedisTemplate.opsForValue().set(String.format("mq:s1:%s", ++num[0]), "已预订", 5, TimeUnit.SECONDS));
    			log.info("放了 {} 条数据到redis...", max);
    			TimeUnit.SECONDS.sleep(3);
    		}
    	}
    }
    
  5. 定义监听器 实现KeyExpirationEventMessageListener接口

    查看源码发现,该接口监听所有db的过期事件keyevent@*:expired"

    定义Status1ExpirationListener监听状态1到期

    @Slf4j
    @Component
    public class Status1ExpirationListener extends KeyExpirationEventMessageListener {
    
    	public Status1ExpirationListener(RedisMessageListenerContainer listenerContainer) {
    		super(listenerContainer);
    	}
    
    	@Autowired
    	private StringRedisTemplate stringRedisTemplate;
    
    	@Override
    	public void onMessage(Message message, byte[] pattern) {
    		// 用户做自己的业务处理即可,注意message.toString()可以获取失效的key
    		String expiredKey = message.toString();
    		if (expiredKey.startsWith("mq:s1:")) {
    			log.info("-----------------------------------");
    			log.info(String.format("过期key[%s]", expiredKey));
    			String newKey = String.format("mq:s2:%s", expiredKey.substring(6));
    			String newValue = "行程中";
    			stringRedisTemplate.opsForValue().set(newKey, newValue, 3, TimeUnit.SECONDS);
    			log.info(String.format("%s: %s", newKey, newValue));
    			log.info("-----------------------------------");
    		}
    	}
    
    }
    

    定义Status2ExpirationListener监听状态2到期

    @Slf4j
    @Component
    public class Status2ExpirationListener extends KeyExpirationEventMessageListener {
    
    	public Status2ExpirationListener(RedisMessageListenerContainer listenerContainer) {
    		super(listenerContainer);
    	}
    
    	@Override
    	public void onMessage(Message message, byte[] pattern) {
    		// 用户做自己的业务处理即可,注意message.toString()可以获取失效的key
    		String expiredKey = message.toString();
    		if (expiredKey.startsWith("mq:s2:")) {
    			log.info("***********************************");
    			log.info(String.format("过期key[%s]", expiredKey));
    			log.info("[{}]行程已完成,修改数据库状态。", newKey);
    			log.info("***********************************");
    		}
    	}
    
    }
    

四、测试输出

...
2021-01-25 23:16:58.012  INFO 55511 --- [           main] n.y.tools.listener.ProviderDataToRedis      : 放了 4 条数据到redis...
2021-01-25 23:17:00.037  INFO 55511 --- [ container-1070] c.i.r.l.Status1ExpirationListener        : -----------------------------------
2021-01-25 23:17:00.037  INFO 55511 --- [ container-1070] c.i.r.l.Status1ExpirationListener        : 过期key[mq:s1:272]
2021-01-25 23:17:00.037  INFO 55511 --- [ container-1072] c.i.r.l.Status1ExpirationListener        : -----------------------------------
2021-01-25 23:17:00.037  INFO 55511 --- [ container-1072] c.i.r.l.Status1ExpirationListener        : 过期key[mq:s1:271]
2021-01-25 23:17:00.039  INFO 55511 --- [ container-1070] c.i.r.l.Status1ExpirationListener        : mq:s2:272: 行程中
2021-01-25 23:17:00.039  INFO 55511 --- [ container-1072] c.i.r.l.Status1ExpirationListener        : mq:s2:271: 行程中
2021-01-25 23:17:00.039  INFO 55511 --- [ container-1070] c.i.r.l.Status1ExpirationListener        : -----------------------------------
2021-01-25 23:17:00.039  INFO 55511 --- [ container-1072] c.i.r.l.Status1ExpirationListener        : -----------------------------------
2021-01-25 23:17:00.140  INFO 55511 --- [ container-1075] c.i.r.l.Status2ExpirationListener        : ***********************************
2021-01-25 23:17:00.140  INFO 55511 --- [ container-1075] c.i.r.l.Status2ExpirationListener        : 过期key[mq:s2:270]
2021-01-25 23:17:00.140  INFO 55511 --- [ container-1075] c.i.r.l.Status2ExpirationListener        : [270]行程已完成,修改数据库状态。
2021-01-25 23:17:00.140  INFO 55511 --- [ container-1075] c.i.r.l.Status2ExpirationListener        : ***********************************
2021-01-25 23:17:00.242  INFO 55511 --- [ container-1077] c.i.r.l.Status2ExpirationListener        : ***********************************
2021-01-25 23:17:00.242  INFO 55511 --- [ container-1077] c.i.r.l.Status2ExpirationListener        : 过期key[mq:s2:269]
2021-01-25 23:17:00.242  INFO 55511 --- [ container-1079] c.i.r.l.Status2ExpirationListener        : ***********************************
2021-01-25 23:17:00.242  INFO 55511 --- [ container-1079] c.i.r.l.Status2ExpirationListener        : 过期key[mq:s2:268]
2021-01-25 23:17:00.242  INFO 55511 --- [ container-1077] c.i.r.l.Status2ExpirationListener        : [269]行程已完成,修改数据库状态。
2021-01-25 23:17:00.242  INFO 55511 --- [ container-1077] c.i.r.l.Status2ExpirationListener        : ***********************************
2021-01-25 23:17:00.242  INFO 55511 --- [ container-1079] c.i.r.l.Status2ExpirationListener        : [268]行程已完成,修改数据库状态。
2021-01-25 23:17:00.242  INFO 55511 --- [ container-1079] c.i.r.l.Status2ExpirationListener        : ***********************************
2021-01-25 23:17:00.546  INFO 55511 --- [ container-1081] c.i.r.l.Status2ExpirationListener        : ***********************************
2021-01-25 23:17:00.546  INFO 55511 --- [ container-1081] c.i.r.l.Status2ExpirationListener        : 过期key[mq:s2:267]
2021-01-25 23:17:00.546  INFO 55511 --- [ container-1081] c.i.r.l.Status2ExpirationListener        : [267]行程已完成,修改数据库状态。
2021-01-25 23:17:00.546  INFO 55511 --- [ container-1081] c.i.r.l.Status2ExpirationListener        : ***********************************
...

五、一直增加的线程数

从测试输出的日志中可以看出,线程一直在增加,这个问题还有待解决!

六、参考

http://redisdoc.com/topic/notification.html

转:

【Redis系列】Spring boot实现监听Redis key失效事件

标签:25,01,container,23,Redis,boot,---,2021,key
来源: https://www.cnblogs.com/wangtcc/p/14615556.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有