項目產品中,大家都會有"定時任務"和"定時超時"的需求,初始階段,我們基本都是用少數的一些timer,即使是任務量越來越大的時候,我們就難免維護著大量的timer,或者進行了大量低效的掃描。
定時任務使用場景:當訂單一直處于未支付狀態時,如何及時的關閉訂單(已經使用)
如何定期檢查處于退款狀態的訂單是否已經退款成功(后期重構使用)
設計方案:
咱們公司現階段就是使用的這套方法:
1.新增一個job,會job_pool中插入一條數據,記錄了業務方消費方。也會在bucket插入一條記錄,記錄執行的時間戳
2.搬運線程會去bucket中查找哪些執行時間戳的RunTimeMillis比現在的時間小,將這些記錄全部刪除;同時會解析出每個任務的Topic是什么,然后將這些任務PUSH到TOPIC對應的列表queue中
3每個topic的list都會有一個監聽線程去批量獲取list中的待消費數據,獲取到的數據全部扔給這個topic的消費線程池
4.消費線程池執行會去job_pool查找數據結構,返回給回調結構,執行回調方法。
圖片
待優化的內容:
一般來說還有什么其他方法實現這類需求呢?
“輪詢掃描法”
1.用一個Map<uid, last_packet_time>來記錄每一個uid最近一次請求時間last_packet_time
2.當某個用戶uid有請求包來到,實時更新這個Map
3.啟動一個timer,當Map中不為空時,輪詢掃描這個Map,看每個uid的last_packet_time是否超過30s,如果超過則進行超時處理
“多timer觸發法”
1.用一個Map<uid, last_packet_time>來記錄每一個uid最近一次請求時間last_packet_time
2.當某個用戶uid有請求包來到,實時更新這個Map,并同時對這個uid請求包啟動一個timer,30s之后觸發
3.每個uid請求包對應的timer觸發后,看Map中,查看這個uid的last_packet_time是否超過30s,如果超過則進行超時處理
方案一:只啟動一個timer,但需要輪詢,效率較低
方案二:不需要輪詢,但每個請求包要啟動一個timer,比較耗資源
ZSet(有序集合)數據結構來實現
import redis.clients.jedis.Jedis;import redis.clients.jedis.Tuple;import java.util.Set;public class OrderCancellationSystem { public static void main(String[] args) { Jedis jedis = new Jedis("localhost"); // 連接到本地Redis服務器 // 模擬添加訂單 addOrder(jedis, "Order1"); addOrder(jedis, "Order2"); // 定時任務,每分鐘檢查訂單并自動取消 while (true) { cancelLongUnpaidOrders(jedis); try { Thread.sleep(60000); // 等待一分鐘再次檢查 } catch (InterruptedException e) { e.printStackTrace(); } } } public static void addOrder(Jedis jedis, String orderId) { long currentTime = System.currentTimeMillis(); jedis.zadd("orders", currentTime, orderId); } public static void cancelOrder(String orderId) { // 執行取消訂單操作,例如更新訂單狀態 System.out.println("Cancelling order: " + orderId); } public static void cancelLongUnpaidOrders(Jedis jedis) { long expirationTime = System.currentTimeMillis() - 3600 * 1000; // 60分鐘前的時間戳 Set<Tuple> longUnpaidOrders = jedis.zrangeByScoreWithScores("orders", "-inf", String.valueOf(expirationTime)); for (Tuple order : longUnpaidOrders) { String orderId = order.getElement(); cancelOrder(orderId); jedis.zrem("orders", orderId); // 從ZSet中刪除已取消的訂單 } }}
本文鏈接:http://www.www897cc.com/showinfo-26-17398-0.html數十萬定時任務,如何高效觸發定時和超時
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 了解 Go 中原子操作的重要性與使用方法