Redisson 和redis 实现延迟消息

Redis 是数据库/中间件,Redisson 是 Java 操作 Redis 的客户端和工具库。

可以这样理解:

复制代码
Redis:服务端
Redisson:Java 客户端

就像:

复制代码
MySQL 是数据库
JDBC / MyBatis 是 Java 访问 MySQL 的工具

对应到 Redis:

复制代码
Redis 是内存数据库
Redisson 是 Java 访问 Redis,并基于 Redis 实现分布式能力的框架

Redis 本身提供什么

Redis 本身提供的是基础能力:

复制代码
String
Hash
List
Set
ZSet
过期时间
Lua 脚本
发布订阅
Stream
持久化
主从复制
哨兵
集群

它本质上是一个高性能的内存数据存储系统。

Redisson 提供什么

Redisson 是在 Redis 基础上封装了一层 Java API,提供更高级的分布式工具,比如:

复制代码
分布式锁 RLock
延迟队列 RDelayedQueue
阻塞队列 RBlockingQueue
分布式集合 RMap / RSet / RList
信号量 RSemaphore
倒计时锁 RCountDownLatch
限流器 RRateLimiter
布隆过滤器 RBloomFilter

你在项目里写的:

复制代码
Redisson 分布式锁
Redisson 延迟队列

底层其实还是用 Redis 存储数据和执行命令,只是 Redisson 帮你把复杂逻辑封装好了。


举个例子:分布式锁

如果只用 Redis,分布式锁一般要自己写:

复制代码
SET lock_key unique_value NX PX 30000

释放锁时还要用 Lua 脚本保证只能释放自己的锁。

Redisson 帮你封装成:

复制代码
RLock lock = redissonClient.getLock("order:payment:lock:" + orderId);
lock.tryLock();
lock.unlock();

底层还是 Redis 的命令和 Lua 脚本,但你不用自己处理:

复制代码
加锁原子性
锁过期
误删锁
看门狗续期
可重入
释放锁安全性

举个例子:延迟队列

Redis 本身没有一个直接叫"延迟队列"的完整业务组件。

但可以基于 Redis 的数据结构实现,比如:

复制代码
ZSet 存任务,score 是执行时间
后台线程扫描到期任务
到期后转移给消费者处理

Redisson 把这套能力封装成:

复制代码
RBlockingQueue<OrderTimeoutTask> blockingQueue =
    redissonClient.getBlockingQueue("order:timeout:queue");

RDelayedQueue<OrderTimeoutTask> delayedQueue =
    redissonClient.getDelayedQueue(blockingQueue);

delayedQueue.offer(task, 30, TimeUnit.MINUTES);

你用起来像延迟队列,但底层仍然依赖 Redis。

redis

1.Redis Key 过期监听 (Keyspace Notifications)
  • 实现原理: 利用 Redis 的发布/订阅(Pub/Sub)机制。应用监听 keyevent@0:expired 这个频道,当往 Redis 放一个带过期时间(TTL)的 Key,

  • Key 过期时 Redis 会自动发布一条消息,应用收到消息后执行逻辑。

  • 致命痛点(为什么说会"丢失"):

    • Pub/Sub 机制不保证可靠性: Redis 的发布订阅是"发后既忘"(Fire and Forget)的。如果 Key 过期时,你的 Java 后端服务刚好宕机、重启,或者发生网络抖动(Downtime),这条通知就彻底丢了,没有任何重试机制。

    • 过期时间的延迟: Redis 的过期删除策略是"惰性删除 + 定期删除"。如果 CPU 负载较高,Redis 可能无法在 TTL 到期的那一毫秒精准删除 Key,导致通知发出时间滞后。

  • 企业级纠正(面试加分项): 如果非要在 Redis 里做延时队列,正确的做法不是 用过期监听,而是用 Redisson RDelayedQueue 。它底层是基于 Redis 的 ZSET(有序集合)实现的,按执行时间戳作为 Score 进行排序,并用后台线程不断拉取到期的任务。这种方式既不会丢数据,也能抗住高并发。

2.通过redission延迟队列(基于的 "ZSet(有序集合)+ List(列表)" 实现)

流程:

先把任务放到一个延迟队列里RDelayedQueue 到期后 Redisson 把任务转移到阻塞队列RBlockingQueue 消费者从阻塞队列取任务执行

RDelayedQueue:存还没到时间的任务

RBlockingQueue:存已经到期、可以消费的任务

复制代码

基于 Redis 封装的延迟任务能力,比 key 过期监听更工程化,适合轻量级延迟任务。

相关推荐
西凉的悲伤1 小时前
redis和数据库实现分布式锁
java·数据库·redis·分布式
zhougl9961 小时前
Database(数据库)和 Schema(模式)
数据库·oracle
专注API从业者1 小时前
告别手动翻页!基于淘宝商品接口 + Open Claw 实现自动化选品与实时监控(附完整 Python 代码)
大数据·运维·数据库·自动化
曹牧1 小时前
Oracle:xml转义
xml·数据库·oracle
湖南天硕国产SSD1 小时前
工业存储可靠性进阶:天硕工业固态硬盘动态温控与寿命优化技术实践
网络·数据库·算法·工业存储·天硕存储·工业固态硬盘
我星期八休息1 小时前
Linux系统编程— Mmap实现⽂件LRU缓存
linux·运维·服务器·数据库·mysql·缓存
_白格1 小时前
计算机内存相关知识总结
缓存
小此方1 小时前
Re:Mysql数据库基础篇(三):全面掌握数据库与数据表操作:深度剖析底层文件差异与核心管理机制
数据库·mysql
涛思数据(TDengine)2 小时前
时序数据库 TDengine 在能碳管理平台中的关键技术选型与落地实践
数据库·时序数据库·tdengine