PHP實現的毫秒定時器,同時解決程序不重複堆積
阿新 • • 發佈:2018-12-10
定時器任務,在WEB應用比較常見,如何使用PHP實現定時器任務,大致有兩種方案:1)使用Crontab命令,寫一個shell指令碼,在指令碼中呼叫PHP檔案,然後定期執行該指令碼;2)配合使用ignore_user_abort()和set_time_limit(),使指令碼脫離瀏覽器執行。前者是利用Linux的特性,和PHP本身沒有多大關係,後者使用場景有限,且只能由一次HTTP請求觸發該指令碼,執行完後退出。那麼我們如何使用純PHP實現純粹的定時器任務,且能適應認識任務業務需求?
基於cli模式執行,依賴php擴充套件 swoole
因該定時器支援毫秒,時間間隔較小,未來防止程序堆積,做了程序判斷,程序存在就本次停止,等待下一次執行。
<?php /** * 基於swoole 毫秒定時器 * */ // 當前的執行環境是否是cli模式 function is_cli() { return preg_match("/cli/i", php_sapi_name()) ? true : false; } /** * 計劃任務定時檢測master程序是否存在,不存在則啟動,以root使用者執行 * shell基本命令 *(1)ps aux 顯示系統全部程序,一行一個 *(2)grep “abc” 從標準輸入讀取字元流,輸出包含字串“abc”的行 *(3)grep -v "acb" 從標準輸入讀取字元流,輸出不包含字串“grep”的行 *(4)wc -l 從標準輸入讀取字元流,輸出行數 * * */ function checkMaster() { $cmd = 'ps axu | grep "consume" | grep -v "grep" | wc -l'; $ret = shell_exec("$cmd"); $ret = rtrim($ret, "\r\n"); echo "檢視程序:".$ret."===". $cmd . "\n"; return $ret; } if (is_cli()) { swoole_timer_tick(2000, function () { // 判定程序是否存在 $ret = checkMaster(); if ($ret === "0") { $start_master_cmd = "/usr/bin/php /var/www/html/cctv/Html/index.php /Home/TaskSi/consume.html >> /var/www/html/cctv/Runtime/Logs/huisu_si.log &"; $ret = shell_exec("$start_master_cmd"); // var_dump($ret); echo '開啟程序:' . $start_master_cmd . "\n==============================\n"; } else { echo "程序已存在~~休息一下~~(".$ret.")\n==============================\n"; } }); } else { exit("非cli模式,已經停止執行!\n"); }