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

相关推荐
这个DBA有点耶2 小时前
AI写的SQL跑崩了生产库,这锅谁背?
数据库·人工智能·程序员
镜舟科技2 小时前
Databricks 再提 LTAP,AI 时代的数据底座为何重回大一统叙事?
数据库·架构·agent
Databend3 小时前
从湖仓升级为 Agent 时代的数据控制面,Snowflake 和 Databricks 有哪些布局
大数据·数据库·agent
ClouGence6 小时前
SQL Server CDC 能放到 Always On 备库读吗?一文讲透原理与实践
数据库·sql server
先吃饱再说1 天前
存储的进化:从 MySQL 到浏览器缓存,数据到底住在哪?
数据库
Nturmoils1 天前
字段太多看不全,ksql 的展开模式和输出控制怎么用
数据库·后端
Databend1 天前
Agent 轨迹分析与归因的数据工程实践
大数据·数据库·agent
这个DBA有点耶1 天前
SQL改写进阶:标量子查询的“隐形代价”与消除实战
数据库·mysql·架构
smallyoung1 天前
数据库乐观锁深度解析:MySQL、PostgreSQL 实战 + Spring Boot 集成指南
数据库·mysql·postgresql
parade岁月1 天前
MySQL JOIN解析:朴实无华但食之有味
数据库·后端