![7be1388f92ac1e1f512b6120dc9a75c1.png](https://i-blog.csdnimg.cn/blog_migrate/e1b14d4adea25c0230340e9b32f98196.jpeg)
我的业务场景
系统管理员要给维护员分配巡查路口设施的工作,由于路口比较多,管理员不知道哪些路口已经被分配了,况且过了一个时间周期后,所有的路口要再次被巡查。
思路
我建立了一个表,里面是所有路口和是否已经分配的状态
利用redis的键过期事件来做这个业务。
- 管理员给维护员分配了路口的时候把那些路口状态修改为不可分配,然后把路口添加到redis,以intersection:开头+id作为key,value为"",设置上过期时间(这个过期时间就是那个时间周期)。
- 管理员查询路口时默认只查看可分配状态的路口。
- 利用redis的键过期事件通知得到key,再把路口id解析出来,然后修改该路口状态为可分配。
修改redis配置文件,以windows版本为例
把 notify-keyspace-events的值修改未 Ex ,默认的可能是**notify-keyspace-events "" **,然后重启redis
测试
开一个redis客户端1
#redis目录下 注意__是由两个下划线组成的 127.0.0.1:6379> psubscribe __keyevent@0__:expiredReading messages... (press Ctrl-C to quit)1) "psubscribe"2) "__keyevent@0__:expired"3) (integer) 1
再开一个redis客户端2
127.0.0.1:6379> set a 111 ex 5
客户端1的结果
1) "pmessage"2) "__keyevent@0__:expired"3) "__keyevent@0__:expired"4) "a"
keyevent@0:expired解析
key 键
event 事件
@0 第0个数据库
expired 过期
不懂的可以多搜搜相关资料,我也是第一次弄! 坐标
上代码
添加依赖 不贴版本了
org.apache.commonscommons-pool2 org.springframework.bootspring-boot-starter-data-redis
redis配置 redis的database要和下面的Java代码里写的一样!!!!!!
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver password: 123456 url: jdbc:mysql://localhost:3306/zhjtyw-dev?characterEncoding=UTF8&useSSL=false&serverTimezone=GMT%2B8 username: root redis: database: 0 host: 127.0.0.1 lettuce: pool: max-active: 8 max-idle: 8 max-wait: -1 min-idle: 0 port: 6379 password: 123456 cache: type: redis
配置redis监听器
/** * @author: taoym * @date: 2020/7/23 9:34 * @desc: redis监听器 */@Configurationpublic class RedisListenerConfig { @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); return container; }}
配置
/** * @author: taoym * @date: 2020/7/23 9:38 * @desc: 监听器 */@Component@Slf4jpublic class RedisKeyExpirationListener extends KeyExpirationEventMessageListener { @Autowired private IntersectionPatrolStatusService intersectionPatrolStatusService; // 配置监听哪个频道 private static final Topic KEYEVENT_EXPIRED_TOPIC = new PatternTopic("__keyevent@0__:expired"); public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Override protected void doRegister(RedisMessageListenerContainer listenerContainer) { // 频道可以是多,多个传list listenerContainer.addMessageListener(this,KEYEVENT_EXPIRED_TOPIC); } /** * @author: taoym * @date: 2020/7/17 16:12 * @desc: redis失效事件 */ @Override public void onMessage(Message message, byte[] pattern) { // 用户做自己的业务处理即可,注意message.toString()可以获取失效的key String expiredKey = message.toString(); expiredKey = expiredKey.substring(1,expiredKey.length()-1); if(expiredKey.startsWith("intersection"+ RegexConstant.COLON)){ String[] split = expiredKey.split(RegexConstant.COLON); Integer id = Integer.valueOf(split[1]); ReqUpdateIntersectionPatrolStatusDTO data = new ReqUpdateIntersectionPatrolStatusDTO(); data.setId(id); data.setStatus(IntersectionPatrolStatusEnum.CAN_DISTRIBUTION.getCode()); int i = intersectionPatrolStatusService.updateIntersectionPatrolStatus(data); log.info("巡查路口的周期已经过,可以开始下次巡查"); } }}
结束语
利用redis的键过期事件能做很多事,多多探索,多从网上查查资料!
来源:https://www.tuicool.com/articles/jmMf2iA