PHP實現的毫秒定時器,同時解決進程不重複堆積

定時器任務,在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");
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章