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

相关推荐
晚染烟8 小时前
每日八股day17
redis
小白勇闯网安圈8 小时前
Django 响应对象、文件上传与类视图
数据库·django·sqlite
努力的小雨9 小时前
同一份 SQL 跑多套环境:Ksql 变量怎么用才安全
数据库
m0_3807438710 小时前
给大模型调用加一层本地缓存,让重复请求直接命中磁盘
缓存
科技绘图10 小时前
快鲸GEO vs 传统AI搜索优化:全链路自动化与高效内容生产在转化闭环上的对比
数据库·人工智能·自动化
ltl10 小时前
数据库作为 LLM 记忆体:语义缓存、RAG 与一致性
数据库
ltl10 小时前
WAL 与崩溃恢复:ARIES 协议怎么跑通
数据库
ltl10 小时前
TEE 数据库:EnclaveDB、Oblivious 原语与机密 SQL
数据库
麻瓜code11 小时前
【Mysql】重新学一遍 SQL 执行顺序
数据库·sql
FakeOccupational12 小时前
【电路笔记 STM32】Cortex-M7 内核上的数据缓存(D-Cache)结构+MPU+DMA&Cache+STM32CubeMX配置
笔记·stm32·缓存