摘要:我們項目使用的是框架,所以我就想到用框架的定時器。,以及的結構注在定時器這塊使用到兩個一個是用于存儲任務的實例。
這兩天老大給了個需求想把商城熱點數據同步到redis緩存。我們項目使用的是swoft框架,所以我就想到用框架的Crontab定時器。但是在測試的時候發現把Table的size設置為1024時(實際上設置為任何大小都一樣,貼上swoole的解釋)發現內存溢出了
普及一下Table(來自swoole文檔):
Table底層是建立在共享內存之上的HashTable數據結構。$size最大行數,決定了HashTable的總行數。由于Table是在共享內存之上,所以無法動態擴容。這個$size必須在創建前設置好。
$size參數指定表格的最大行數,如果$size不是為2的N次方,如1024、8192,65536等,底層會自動調整為接近的一個數字,如果小于1024則默認成1024,即1024是最小值
先把框架任務投遞流程走一下:
首先當框架啟動一秒后,啟動定時器每秒去更新執行一次Task(任務)。更新任務之前先去隊列內存表中清理已完成的隊列數據(這點很重要)
然后獲取出所有的任務中的隊列(可以理解為獲取所有的Task類中的方法),以任務規則,以及taskClass,分鐘,時間戳這些數據以md5方式加密得到每個任務隊列的key值,保存在runTimeTable 中。(originTable,以及runTimeTable 的結構)
注:在定時器這塊使用到兩個Table 一個是originTable用于存儲任務的(Task)實例。另一個是runTimeTable 存儲任務隊列實例,通俗地說就是存需要執行的任務實例
再看看任務執行流程,任務的執行就很簡單了
首先通過getExecTasks這個方法把所有滿足條件的隊列任務放在一個數組,然后通過遍歷數據把runStatus的值改為self::START
之后執行所有runStatus的值為self::START的隊列任務
把執行后的隊列任務的runStatus的值改為self::FINISH
最后把runStatus的值改為self::FINISH的剔除掉
重新梳理一下我們邏輯
當我們新建執行一個任務的時候,系統每秒鐘都回去更新執行一個每個任務中的隊列數。
代碼如下:
通過代碼我們能夠發現每一分鐘他都會往runTimeTable 中添加60個任務隊列
但是當我們getExecTasks獲取將要執行的任務隊里的時候是根據當前的時候是否等于執行時間而標志狀態的
那么現在就會出現一個問題。當前時間往任務隊里中添加數據的時候 他把前面執行過的任務隊列再次添加進runTimeTable 中
舉個栗子:
假如我有個異步任務Sync,其中有個每秒執行一次的方法cronTask,
現在時間是2019-03-22 10:01:20 現在往更新runTimeTable 的時候 他會往里面添加60的任務隊列key分別會是
MD5(" "."Sync"."cronTask"."01"."00")
MD5(" "."Sync"."cronTask"."01"."01")
MD5(" "."Sync"."cronTask"."01"."02")
MD5(" "."Sync"."cronTask"."01"."03")
MD5(" "."Sync"."cronTask"."01"."04")
...
MD5(" "."Sync"."cronTask"."01"."59")
當時間到下一秒(是2019-03-22 10:01:21)的時候后 依然會往更新runTimeTable數據 key值為
MD5(" "."Sync"."cronTask"."01"."00")
MD5(" "."Sync"."cronTask"."01"."01")
MD5(" "."Sync"."cronTask"."01"."02")
MD5(" "."Sync"."cronTask"."01"."03")
MD5(" "."Sync"."cronTask"."01"."04")
...
MD5(" "."Sync"."cronTask"."01"."59")
那么我們可以很明確地看出來在2019-03-22 10:01:21秒前的數據都是沒用的了 。這些數據永遠不會被消費,也不會被刪除。因此一段時間后會出現內存溢出的情況。
所以解決方法是在清理消費數據的時候把過期數據也同時清理
把cleanRunTimeTable中的
if ($value["runStatus"] === self::FINISH) {
改為
$currentTime = time(); if ($value["runStatus"] === self::FINISH || $value["sec"] < $currentTime) {
本文為本人學習過程記錄。如果有哪些地方描述不當望各位大佬指出。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/31065.html
摘要:作為定時任務的執行者,通過每喚醒自身一次,然后把執行表遍歷一次,挑選當下需要執行的任務,通過投遞出去并更新該任務執行表中的狀態。 作者:bromine鏈接:https://www.jianshu.com/p/b44...來源:簡書著作權歸作者所有,本文已獲得作者授權轉載,并對原文進行了重新的排版。Swoft Github: https://github.com/swoft-clou.....
摘要:官網源碼解讀號外號外歡迎大家我們開發組定了一個就線下聚一次的小目標里面的框架算是非常重的了這里的重先不具體到性能層面主要是框架的設計思想和框架集成的服務讓框架可以既可以快速解決很多問題又可以輕松擴展中的框架有在應該無出其右了這次解讀的源碼 官網: https://www.swoft.org/源碼解讀: http://naotu.baidu.com/file/8... 號外號外, 歡迎大...
摘要:在中的應用官網源碼解讀號外號外歡迎大家我們開發組定了一個就線下聚一次的小目標上一篇源碼解讀反響還不錯不少同學推薦再加一篇講解一下中使用到的功能幫助大家開啟的實戰之旅服務器開發涉及到的相關技術領域的知識非常多不日積月累打好基礎是很難真正 date: 2017-12-14 21:34:51title: swoole 在 swoft 中的應用 swoft 官網: https://www.sw...
摘要:在使用腳本實現功能時發現并沒有定時運行在指令后面添加指令,發現如下報錯腳本單獨運行是正常的,但是已使用后運行異常,再一番后發現,是不能正確加載的環境變量導致,需要做如下修改這里是列表文本直接執行所在路徑,路徑可以使用指令來獲取,所以我的在使用Python腳本實現DDNS功能時發現并沒有定時運行在指令后面添加>/dev/null 2&>1指令,發現如下報錯00-18-01 Traceback ...
摘要:官網全站實踐正式來襲也迎來自己的一個里程碑數正式突破官網作為項目組服務開發者們的重要渠道也迎來了自己的一次重大更新重構升級到全站實現本篇先介紹官網全站實踐先來一張官網效果圖鎮樓靜態資源由托管開啟業務代碼交由執行設置使用協議要實現非常簡單 date: 2018-3-8 13:50:03title: Swoft| Swoft官網全站 HTTP2 實踐 Swoft1.0正式來襲, Swoft...
閱讀 638·2021-11-25 09:43
閱讀 1906·2021-11-17 09:33
閱讀 824·2021-09-07 09:58
閱讀 2062·2021-08-16 10:52
閱讀 482·2019-08-30 15:52
閱讀 1722·2019-08-30 15:43
閱讀 974·2019-08-30 15:43
閱讀 2924·2019-08-29 16:41