首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 長時間執行任務實作:ignore_user_abort 與 set_time_limit 應用

     編輯:PHP 綜合知識

核心設定:讓腳本脫離瀏覽器獨立執行

<?php
ignore_user_abort(true);  // 關閉瀏覽器仍持續執行
set_time_limit(0);        // 移除執行時間限制(0 表無限制)

固定間隔執行迴圈範例

$interval = 60 * 30; // 每 30 分鐘執行一次

do {
    // ====== 這裡放入實際業務邏輯 ======
    // 例如:資料同步、報表產生、快取清理、郵件發送等
    // ===================================

    sleep($interval); // 休眠等待下一輪
} while (true);

關鍵風險與改善方向

風險說明建議方案
記憶體洩漏長期運行累積記憶體導致 OOM定期重啟、使用生成器、及時 unset 大變數
單點故障腳本掛掉無自動恢復Systemd/Supervisor 監控自動重啟
並發衝突多實例同時執行造成資料不一致檔案鎖/資料庫鎖/Redis 分散式鎖
執行時間漂移sleep 不精確導致間隔偏移計算下次執行時間點精確 sleep
無優雅關閉收到 SIGTERM 直接中斷註冊 pcntl_signal 處理訊號

生產環境推薦架構

  1. 系統排程器:Linux cron / Windows Task Scheduler(最簡單可靠)
  2. 工作佇列:Redis + PHP Worker / Laravel Horizon / Gearman
  3. 進程管理器:Supervisor 管理常駐 PHP 進程
  4. 容器化:Kubernetes CronJob 定時啟動容器執行任務

改良版迴圈(含訊號處理與精確間隔)

<?php
declare(ticks = 1);
$shutdown = false;
pcntl_signal(SIGTERM, function() use (&$shutdown) { $shutdown = true; });
pcntl_signal(SIGINT, function() use (&$shutdown) { $shutdown = true; });

ignore_user_abort(true);
set_time_limit(0);
$interval = 1800; // 30 分鐘
$nextRun = time() + $interval;

while (!$shutdown) {
    $start = microtime(true);
    
    // 業務邏輯
    doTask();
    
    // 精確計算下次執行時間
    $elapsed = microtime(true) - $start;
    $sleepTime = max(1, $interval - $elapsed);
    sleep((int)$sleepTime);
    usleep(($sleepTime - (int)$sleepTime) * 1_000_000);
}

function doTask() {
    // 實際任務邏輯
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved