延時任務最佳實踐方案

2021-10-10 01:21:00 字數 1535 閱讀 5559

總結很多時候,業務系統有延時處理任務的需求,當任務量很大時,可能需要維護大量的定時器,或者進行低效的掃瞄。例如:電商下單成功後60s之後給使用者傳送簡訊通知,電商下單後30分鐘未支付,則自動取消訂單;出行乘客叫單後30秒沒有司機接單,重新給周邊司機推單等。實現這類需求有一些常見方案。

在討論方案前我們需要搞清楚,延時任務與定時任務究竟有啥區別?定時任務有明確的執行時間或週期性,比如定時充電,要選開始充電的具體時間點,再比如每10分鐘做一次未支付訂單的狀態檢查。而延時任務沒有這些特性,它具有不確定性,是在某個事件觸發後一段時間內執行。下面以「出行乘客叫單後30秒內沒有司機接單,重新給周邊司機推單,直到司機接單」為例,講解每種方案的實現。

啟動乙個timer,30秒間隔輪詢掃瞄訂單表,檢查每個未接訂單建立時間是否超過30秒的整數倍,如果超過,重新給周邊司機推送訂單。

優點:簡單易行。

缺點:如果訂單量過大,延遲會比較高。

適用範圍:這種方案一般適用於延時任務量比較少,對於延時精確度要求不高的任務。

為每個訂單建立乙個timer,並且設定為30秒的觸發時間間隔,事件觸發後檢查訂單狀態,如果是初始狀態,則繼續執行,否則停止並釋放timer。

優點:簡單易行,不需要輪詢,精確度較高。

缺點:但每個訂單要啟動乙個timer,比較耗資源。

適用範圍:同樣適用於延時任務量比較少的系統。

死信:dead letter,是指被拒絕或ttl過期或佇列已達到最大長度限制,無法再入隊的訊息。利用dlx,當訊息在乙個佇列中變成死信之後,它能被重新publish到另乙個exchange,這個exchange就是dlx。

死信佇列生產消費模型:

利用死信佇列可以實現延時任務,每個訂單建立乙個訊息,訊息的ttl被設定為30秒。當訊息過期後,通過交換機**給業務消費佇列,消費處理程式訂閱業務消費佇列,有訊息則進行處理,檢查訂單狀態,如果是初始狀態,則重新對該訂單建立乙個訊息。

優點:不需要輪詢,精確度高。

缺點:引入訊息元件,系統複雜度提高。

適用範圍:適用於有大量延時任務需求的系統。

環形佇列本質上就是乙個陣列,收尾相接,形成了乙個環。陣列中的每個索引位稱為槽(slot),每個槽中放乙個集合,用於盛放需要處理的任務。啟動乙個timer,從slot=0處開始,每秒鐘向前移動一次,拿到當前slot中任務資料進行處理,直到陣列的最後乙個slot,再從slot=0開始,迴圈往復。

環形佇列任務處理流程:

實際的業務場景中還要考慮任務不丟失,故障恢復等問題,所以增加了持久化任務佇列,將新加入槽中的任務持久化到redis,和移除任務佇列,將處理完的任務從redis清除,程序故障恢復後初始化時將存在到redis中的任務還原到環形佇列的相應槽位中。

推單任務處理模型:

延時任務與定時任務

1.延時任務 at命令的使用 1 開啟終端,在根目錄下建立乙個新的目錄取名為 at 2 進入 at目錄下,執行watch n 1 ls l at命令,對其進行監控 3 同時開啟另乙個終端,執行命令 at 某個將來的具體時刻 表示將來在某個時刻執行你特定的操作 例如下圖便是在17 20在 at目錄下建...

延時任務和定時任務

1.at 延時 at l 檢視任務 at r 任務編號 刪除任務 etc at.allow 白名單,白名單中存在的使用者可以使用at,白名單優先順序高,黑白名單中使用者同時存在,白名單生效 etc at.deny 黑名單,存在的使用者不能使用at 2.crontab 定時 由crond.servic...

分布式系統延時任務方案

在實際專案開發中,我們遇到了如下需求 1,機票訂單下單後,如果30分鐘內未支付,則自動取消 2,產品上架後,24小時都沒有人買,則自動下架 3,一定時間後自動評價或者自動收貨 4,其他類似需求.類似這樣的需求,我把它叫做延時任務,叫做定時任務不大合適,因為這類任務沒有固定的觸發時間,下面我們來分析總...