利用RedissonRelayedQueue 实现,如果超过订单交期后,将订单设置为甩期
你的需求是:当一个订单超过交期后,自动将其标记为“甩期”状态。这本质上是一个延迟触发的业务逻辑。
我们可以使用 RedissonRelayedQueue 来实现订单的“甩期”逻辑,但为了支持延迟处理,还需要结合 Redisson 提供的 延迟队列(RDelayedQueue)功能。
✅ 技术选型
| 功能 | 使用组件 |
|---|---|
| 延迟触发 | RDelayedQueue |
| 消息广播(甩期通知) | RedissonRelayedQueue |
| 消息结构 | 自定义订单 DTO |
| 消息持久化 | Redis(默认) |
🧠 业务逻辑说明
- 订单生成时,如果设置了交期(如 5 分钟后),将订单放入延迟队列。
- 到达交期后,订单被放入目标队列(
RedissonRelayedQueue)。 - 消费者监听目标队列,将订单状态设置为“甩期”。
- 同时,所有监听该队列的节点都能通过广播机制收到该消息(用于分布式系统中同步状态)。
📦 示例代码实现
1. 定义订单 DTO(可序列化)
import java.io.Serializable;
public class Order implements Serializable {
private String orderId;
private long deadline; // 交期时间戳
public Order(String orderId, long deadline) {
this.orderId = orderId;
this.deadline = deadline;
}
public String getOrderId() {
return orderId;
}
public long getDeadline() {
return deadline;
}
@Override
public String toString() {
return "Order{" +
"orderId='" + orderId + '\'' +
", deadline=" + deadline +
'}';
}
}
2. 初始化 Redisson 客户端和队列
import org.redisson.Redisson;
import org.redisson.api.*;
import org.redisson.config.Config;
import java.util.concurrent.TimeUnit;
public class OrderDelayProcessor {
public static void main(String[] args) throws InterruptedException {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
// 创建目标队列(带广播)
RQueue<Order> targetQueue = redisson.getQueue("OrderDelayQueue");
// 创建延迟队列
RDelayedQueue<Order> delayedQueue = redisson.getDelayedQueue(targetQueue);
// 消费者监听目标队列
new Thread(() -> {
while (true) {
try {
Order order = targetQueue.poll(5, TimeUnit.SECONDS);
if (order != null) {
System.out.println("处理甩期订单: " + order.getOrderId());
// 设置订单状态为甩期
handleOrderDelay(order);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}).start();
// 广播监听器(用于通知其他节点)
RTopic<Order> topic = redisson.getTopic("OrderDelayQueue");
topic.addListener((channel, msg) -> {
System.out.println("广播收到甩期订单: " + msg.getOrderId());
});
// 模拟添加一个订单,交期为 10 秒后
String orderId = "ORDER_001";
long delaySeconds = 10;
long deadline = System.currentTimeMillis() + delaySeconds * 1000;
Order order = new Order(orderId, deadline);
delayedQueue.offer(order, delaySeconds, TimeUnit.SECONDS);
System.out.println("订单 " + orderId + " 已添加至延迟队列,将在 " + delaySeconds + " 秒后触发甩期处理");
}
private static void handleOrderDelay(Order order) {
// 实际业务逻辑:更新数据库状态为甩期
System.out.println("订单 [" + order.getOrderId() + "] 已标记为甩期");
}
}
📈 延迟队列原理图解
+-------------------+
| Redisson 客户端 |
| |
| RDelayedQueue |
| ┌──────────────┐|
| │ 延迟存储订单 │|
| └──────┬───────┘|
| │
| 定时检查到期订单
| │
| 转发到目标队列
| ↓
| RQueue<Order> |
| (RedissonRelayedQueue) |
+-------------------+
↓
消费者线程处理订单状态
广播通知其他节点
✅ 优势总结
| 特性 | 是否支持 |
|---|---|
| 延迟处理 | ✅(RDelayedQueue) |
| 消息广播 | ✅(RelayedQueue) |
| 分布式支持 | ✅ |
| 消息持久化 | ✅(可配置) |
| 多消费者支持 | ✅ |
🧩 可扩展性建议
- 持久化订单数据:可以结合 Redis + DB,将订单状态最终持久化到数据库。
- 重试机制:如果处理失败,可将订单重新放回队列或记录日志。
- 监控报警:使用 Redisson 的看门狗机制或外部监控系统来跟踪延迟队列状态。
- 动态设置交期:根据订单类型、优先级等动态设置延迟时间。
📌 后续建议
如果你还需要:
- 多个订单同时处理
- 订单状态更新的幂等性
- 延迟任务取消(如用户提前完成)
- 集群部署下的负载均衡
欢迎继续提问,我可以为你扩展完整架构方案。
是否需要我提供一个 Spring Boot + Redisson 的整合示例?
本文来自博客园,作者:chuangzhou,转载请注明原文链接:https://www.cnblogs.com/czzz/p/19001483

浙公网安备 33010602011771号