10w定時任務,如何高效觸發超時

2021-08-16 07:31:59 字數 1080 閱讀 2874

很多時候,業務有定時任務或者定時超時的需求,當任務量很大時,可能需要維護大量的timer,或者進行低效的掃瞄。

一般來說怎麼實現這類需求呢?

方案一:只啟動乙個timer,但需要輪詢,效率較低

方案二:不需要輪詢,但每個請求包要啟動乙個timer,比較耗資源

廢話不多說,三個重要的資料結構:

1)30s超時,就建立乙個index從0到30的環形佇列(本質是個陣列)

2)環上每乙個slot是乙個set,任務集合

3)同時還有乙個map,記錄uid落在環上的哪個slot裡

同時:1)啟動乙個timer,每隔1s,在上述環形佇列中移動一格,0->1->2->3…->29->30->0…

2)有乙個current index指標來標識剛檢測過的slot

當有某使用者uid有請求包到達時:

1)從map結構中,查詢出這個uid儲存在哪乙個slot裡

2)從這個slot的set結構中,刪除這個uid

3)將uid重新加入到新的slot中,具體是哪乙個slot呢 => current index指標所指向的上乙個slot,因為這個slot,會被timer在30s之後掃瞄到

(4)更新map,這個uid對應slot的index值

哪些元素會被超時掉呢?

current index每秒種移動乙個slot,這個slot對應的set中所有uid都應該被集體超時!如果最近30s有請求包來到,一定被放到current index的前乙個slot了,current index所在的slot對應set中所有元素,都是最近30s沒有請求包來到的。

所以,當沒有超時時,current index掃到的每乙個slot的set中應該都沒有元素。

優勢:(1)只需要1個timer

(2)timer每1s只需要一次觸發,消耗cpu很低

(3)批量超時,current index掃到的slot,set中所有元素都應該被超時掉

這個環形佇列法是乙個通用的方法,set和map中可以是任何task,本文的uid是乙個最簡單的舉例。

10w定時任務,如何高效觸發超時

二 環形佇列法 廢話不多說,三個重要的資料結構 1 30s超時,就建立乙個index從0到30的環形佇列 本質是個陣列 2 環上每乙個slot是乙個set,任務集合 3 同時還有乙個map,記錄uid落在環上的哪個slot裡 同時 1 啟動乙個timer,每隔1s,在上述環形佇列中移動一格,0 1 ...

定時任務沒觸發 10W定時任務,如何高效觸發超時

需求背景 1.延遲訊息功能。例如 滴滴打車訂單完成後,如果使用者一直不評價,48小時後會將自動評價為5星。2.無效連線斷開。在im系統中,客戶端會與服務端建立大量的長連線,當客戶端與服務端30s內沒有心跳的話,需要把這個連線斷開。一 最傳統的方案 建立一張延遲訊息表,滴滴訂單完成後插入一條延遲訊息,...

定時任務高效觸發

圓通處事,方能達到目的 開發中我們經常會遇到一些需要定時來解決的業務場景。比如,有這樣乙個需求 如果連續30s沒有請求包 例如登入,訊息,keepalive包 服務端就要將這個使用者的狀態置為離線 將所有任務都新增到某集合中,定時輪詢掃瞄,如果達到條件則進行相關處理 let map new map ...