迪迦早期精彩文章(希望对大家有所帮助,直接点击即可阅读):
华为大神珍藏版:SpringBoot全优笔记,面面俱到太全了
涨薪60%!从小厂逆袭,坐上美团L8技术专家(附面经+心得)
就离谱?最新Java架构师全路线总结+高频面试题,这也太强了吧!
阿里大佬倾情力荐:Java全线成长宝典,从P5到P8一应俱全!
前段时间,我在内存中实现了一个简单异步通知框架。但由于没有持久化功能,应用重启就会导致数据丢失,且不支持分布式和集群。今天这篇笔记,引入了 Redis 来解决这些问题,以下是几点理由:
- 数据结构丰富,支持 List、Sorted Set 等
- 具有持久化功能,消息的可靠性能得到保证
- 高可用性,支持单机、主从、集群部署
- 项目中已使用,接入成本更低
基于 Redis 实现延时队列也有几种方法,展开详细讲讲。
基于键事件通知实现
Redis 2.8.0 版本以后就具有了 键事件通知(注,还有个键空间通知,注意区别),基于 Pub/Sub 发布订阅实现,详见 官网。而我们正好可以利用这个特性,实现异步通知的延迟功能,数据流转如下:
大概逻辑:当首次通知、或通知失败时,设置(重新设置)在 Redis 对应的 Key 的过期时间,Redis 会监听过期事件,发生事件时通知订阅者,订阅者接收到事件,做逻辑处理。下面看具体的实现。
首先,修改 Redis 端配置打开功能。由于该功能会消耗一些 CPU 性能,所以在配置文件中是 默认关闭 的。Ex表示打开 键过期事件通知,每当有过期键被删除时发送,订阅者能收到 接收到被执行事件的键的名字
notify-keyspace-events Ex
其次,想要在 SpringBoot 中,订阅到 Redis 的事件,也需要两个步骤:
1、继承
org.springframework.data.redis.listener.adapter.MessageListenerAdapter 类,创建自己的监听器
@Component
public class OrderExpireEventListener extends MessageListenerAdapter {
@Override
public void onMessage(Message message, byte[] pattern) {
byte[] body = message.getBody();
String msg = redisWrapper.getRedisTemplate().getStringSerializer().deserialize(body);
// do something...
// 假如通知失败,需要重新计算下次通知时间,设置 Redis
// 至于数据类型,String 即可
}
}
2、将创建的监听器,注册(