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

相关推荐
太理摆烂哥4 分钟前
MySQL表的操作
数据库
lbb 小魔仙6 分钟前
时序数据库是什么?2026 年五款工业时序数据库横评与场景解析
数据库·时序数据库
零基础12310 分钟前
权限管理怎么做?从“资格”与“空间”双维度设计一套可落地的权限体系
java·服务器·数据库
轮子大叔24 分钟前
Redis深入浅出
redis·缓存
小小龙学IT32 分钟前
PostgreSQL 服务端机制与 SQL 实战深度解析:从 MVCC 到查询优化器
数据库·sql·postgresql
l1t39 分钟前
DeepSeek总结的DuckDB 从 JSON 字符串到类型化列
数据库·sql·json
Raas1001 小时前
AI网关能做调用审计吗?MAI Gateway(魔芋企业级AI网关)实战能力深度解读
java·服务器·网络·数据库·gateway·prompt·企业级产品
海绵宝宝转agent1 小时前
2026-10-14算法+面经总结
java·笔记·算法·缓存
foolishlee1 小时前
openGauss同步提交
数据库
旋生万物1 小时前
分形自相似:微服务、缓存、Prompt 模板为什么长一样
人工智能·缓存·微服务·云原生·prompt