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

PHP 定時任務實現方案:ignore_user_abort、sleep 循環與系統級 Crontab 對比

     編輯:PHP 相關知識

PHP 定時/延遲執行三大方案深度對比

PHP 本質是「請求-響應」模型,**不適合長駐進程**執行定時任務。本文對比純 PHP 循環、CLI + 系統 Crontab、工作隊列三種方案優劣與適用場景。

方案一:ignore_user_abort + sleep 循環(不推薦生產)

<?php
ignore_user_abort(true);   // 客戶端斷開腳本繼續跑
set_time_limit(0);         // 無限執行時間

do {
    // 業務邏輯
    file_put_contents('auto.txt', date('c') . "\n", FILE_APPEND);
    sleep(60);             // 延遲 60 秒
} while (true);

缺陷:

  • 佔用一個 PHP-FPM/CLI 進程常駐,記憶體洩漏風險高。
  • 進程掛掉無自動重啟機制(需外部監控)。
  • 部署多實例極難,易發生重複執行。
  • 代碼更新需重啟進程,無熱重載。

方案二:系統 Crontab + PHP CLI(標準生產方案)

# /etc/crontab 或 crontab -e
* * * * * www-data /usr/bin/php /var/www/html/artisan schedule:run >> /dev/null 2>&1

Laravel/Symfony/ThinkPHP 等框架內建**任務調度器**,在 Kernel.php 定義:

// Laravel Kernel.php
protected function schedule(Schedule $schedule) {
    $schedule->command('emails:send')->hourly();
    $schedule->job(new CleanupJob)->dailyAt('02:00');
    $schedule->call(fn() => Cache::flush())->weekly();
}

優勢:系統級可靠性、日誌輪轉、並發控制、無需修改 PHP 代碼即可調整頻率。

方案三:分布式任務隊列(高併發/高可靠)

  • Redis + Laravel Horizon / Symfony Messenger:延遲隊列、優先級、重試、死信隊列。
  • RabbitMQ / Kafka:高吞吐、持久化、多消費者。
  • Gearman / Beanstalkd:輕量級選擇。
// Laravel 延遲派發
ProcessPodcast::dispatch($podcast)->delay(now()->addMinutes(10));

// Symfony Messenger
$bus->dispatch(new SendEmail($email))->delay(600); // 秒

方案選型決策樹

場景推薦方案
簡單定時備份、清理、報表Crontab + CLI
需秒級精度、動態調度Swoole Timer / Workerman / RoadRunner
異步發送郵件、推播、視頻轉碼隊列
分布式多節點、高可用、可視化監控Laravel Horizon / Jenkins / GitLab CI / Airflow
臨時測試、一次性腳本ignore_user_abort + sleep(僅開發機)

生產環境檢查清單

  1. CLI 專用 php.ini(關閉 Xdebug、調大 memory_limit、啟用 OpCache)。
  2. 鎖機制防重複:flock()、Redis SETNX、數據庫唯一索引。
  3. 超時控制:pcntl_alarm、框架內建 Timeout。
  4. 日誌結構化:JSON 格式、ELK 收集、告警規則。
  5. 優雅停機:捕獲 SIGTERM、完成當前任務再退出。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved