10w定時任務,如何高效觸發超時 學習筆記

微信公共號 [架構師之路] 上看到一篇文章 10w定時任務,如何高效觸發超時,學習了下,一些筆記。

關于 Java 定時任務,參見 Java 定時任務 & 任務調度

業務需求

APP實時消息通道系統,對每個用戶會維護一個 APP 到服務器的 TCP 連接,用來實時收發消息,對這個 TCP 連接,有這樣一個需求:
如果連續 30s 沒有請求包(例如登錄,消息,keepalive 包),服務端就要將這個用戶的狀態置為離線

輪詢掃描法 VS 多 Timer 觸發法

方案一 輪詢掃描法:

  1. 用一個 Map<uid, last_packet_time> 來記錄每一個 uid 最近一次請求時間 last_packet_time
  • 當某個用戶 uid 有請求包來到,實時更新對應的 last_packet_time
  • 啟動一個 Timer,當 Map 中不為空時,輪詢掃描這個 Map,看每個 uidlast_packet_time 是否超過 30s,如果超過則進行超時處理

方案二 多Timer觸發法:

  1. 用一個 Map<uid, last_packet_time> 來記錄每一個 uid 最近一次請求時間 last_packet_time
  • 當某個用戶 uid 有請求包來到,實時更新對應的 last_packet_time
    并同時對這個 uid 請求包啟動一個 Timer,30s 之后觸發
  • 當每個 uid 請求包對應的 Timer 觸發后,查看對應的 last_packet_time 是否超過 30s,如果超過則進行超時處理

方案一:只啟動一個 Timer,但需要輪詢,效率較低
方案二:每個請求包要啟動一個 Timer,不需要輪詢,但比較耗資源

環形隊列法

三個重要的數據結構:

  1. 30s 超時,就創建一個 index 從 0 到 30 的環形隊列(本質是個數組)
  • 環上每一個 slot 是一個任務集合 Set<uid>
  • 同時還有一個 Map<uid, index>,記錄 uid 落在環上的哪個 slot 里
    環形隊列法

同時:

  1. 啟動一個 Timer,每隔 1s,在上述環形隊列中移動一格,0->1->2->3…->29->30->0…
  • 有一個 Current Index 指針來標識剛檢測過的 slot

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

  1. Map 結構中,查找出這個 uid 存儲在哪一個 slot 里
  • 從這個 slot 的 Set 結構中,刪除這個 uid
  • uid 重新加入到新的 slot 中,具體是哪一個 slot 呢? Current Index 指針所指向的上一個 slot,因為這個 slot,會被 Timer 在 30s 之后掃描到
  • 更新 Map,這個 uid 對應 slot 的 index

哪些元素會被超時掉呢?
Current Index 每秒種移動一個 slot,這個 slot 對應的 Set<uid> 中所有 uid 都應該被集體超時!
如果最近 30s 有請求包來到,一定被放到 Current Index 的前一個 slot 了,Current Index 所在的 slot 對應 Set 中所有元素,都是最近 30s 沒有請求包來到的。
所以,當沒有超時時,Current Index 掃到的每一個 slot 的 Set 中應該都沒有元素。

優勢:

  1. 只需要1個 Timer
  • Timer 每 1s 只需要一次觸發,消耗 CPU 很低
  • 批量超時Current Index 掃到的 slot,Set 中所有元素都應該被超時掉

總結

這個環形隊列法是一個通用的方法,SetMap 中可以是任何 task,本文的 uid 是一個最簡單的舉例。


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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 轉自架構師之路 一、緣起 很多時候,業務有定時任務或者定時超時的需求,當任務量很大時,可能需要維護大量的timer...
    Gundy_閱讀 1,247評論 0 5
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,991評論 19 139
  • 教程一:視頻截圖(Tutorial 01: Making Screencaps) 首先我們需要了解視頻文件的一些基...
    90后的思維閱讀 4,794評論 0 3
  • 01 有時候,當你說,過了那么久…… 到底有多久呢?你要說的,并不是久不久的問題,而只是在說你沒有忘記! 02 不...
    海新帆影閱讀 462評論 0 1
  • 在現在移動互聯網時代,新媒體公眾號寫推文,內容質量好固然重要,但很多時候別人愿不愿意閱讀更多情況下是看標題的,好的...
    隊友閱讀 2,130評論 12 61