利用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,轉載請注明原文鏈接:http://www.rzrgm.cn/czzz/p/19001483

浙公網安備 33010602011771號