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 过期监听更工程化,适合轻量级延迟任务。

相关推荐
YOU OU5 小时前
Redis基础常识与命令
数据库·redis·缓存
Database_Cool_7 小时前
OLTP 和 OLAP 区别详解:分析型数据库和事务型数据库怎么选(附阿里云 AnalyticDB MySQL 选型指南)
数据库·mysql·阿里云
爱写代码的阿森7 小时前
鸿蒙三方库 | harmony-utils之KvUtil键值型数据库操作详解
数据库·华为·harmonyos·鸿蒙·huawei
Database_Cool_8 小时前
单机 MySQL 迁移到分布式数据库方便吗?阿里云 PolarDB-X 100% MySQL 协议兼容零改造平滑迁移
数据库·分布式·mysql
姜太小白8 小时前
【MySQL】 索引优化实战:解决 WHERE 等值 + IS NULL 查询,TEXT 字段报错 1167 的完整指南
数据库·mysql
窝子面9 小时前
手搓最简前后端协作-node
javascript·数据库
吳所畏惧9 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
DFT计算杂谈9 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型
linux·服务器·网络·数据库·机器学习
HPFBoy9 小时前
log4net 数据库存日志正确配置
数据库