您的位置:首页 > 数据库 > Redis

SpringBoot + Redis 实现键空间通知(keyspace notification)

2021-08-25 14:08 751 查看

TOC

前言

SpringBoot + Redis 可以用 Redis 的键空间通知机制实现类似延迟消息队列的功能 ,Redis2.8 后可以通过键空间通知接收那些以某种方式改变了Redis数据空间的事件通知,关于 Redis 键空间通知的配置 Redis-x64-3.2 键空间通知(keyspace notification) 之前有介绍,这里只是介绍 SpringBoot 中的同理实现。


环境

SpringBoot2.5.3 + Redis-x64-3.2.1


具体实现

  • 启动 redis,配置文件 redis.windows.conf 中设置键空间通知事件为Ex
notify-keyspace-events Ex

  • application.yml
redis:
localhost: localhost
port: 6379
database: 7
password:
# 过期事件订阅,接收7号数据库中所有key的过期事件
listen-pattern: __keyevent@7__:expired
  • Redis 事件广播配置类
import com.coisini.springbootlearn.core.listener.RedisMessageListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.Topic;

@Configuration
public class RedisListenerConfiguration {

@Value("${spring.redis.listen-pattern}")
public String pattern;

@Bean
public RedisMessageListenerContainer listenerContainer(RedisConnectionFactory redisConnection) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnection);

/**
* Topic是消息发布(Pub)者和订阅(Sub)者之间的传输中介
*/
Topic topic = new PatternTopic(this.pattern);

container.addMessageListener(new RedisMessageListener(), topic);
return container;
}
}
  • Redis 事件广播监听器
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;

public class RedisMessageListener implements MessageListener {

/**
* Redis 事件监听回调
* @param message
* @param pattern
*/
@Override
public void onMessage(Message message, byte[] pattern) {
byte[] body = message.getBody();

String expiredKey = new String(body);

System.out.println("监听到已过期的key:" + expiredKey);

/**
* 监听到过期事件回调
* TODO:
*/

}
}
  • 测试接口
@RestController
@RequestMapping("/redis")
public class RedisController {

@Autowired
private StringRedisTemplate redisTemplate;

@GetMapping(value = "/setExpiredVal")
public String setExpiredVal(@RequestParam String name) {
// 设置 20s 后过期
redisTemplate.opsForValue().set("name", name, 20, TimeUnit.SECONDS);
return "setVal is ok";
}

}
  • 访问接口

  • 20s后控制台输出如下:

  • 接下来就可以去处理相应的业务了。

- End -
梦想是咸鱼
关注一下吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: