如何動態(tài)設置定時任務!而不是寫死在Linux Crontab
概述
在軟件開發(fā)中,定時任務是一個常見的需求,尤其是在需要定期執(zhí)行某些操作的場景中。傳統(tǒng)的Linux cron服務雖然強大,但它的靈活性確實有限,尤其是在動態(tài)調(diào)整任務執(zhí)行時間方面。但在實際項目運行中動態(tài)修改任務執(zhí)行時間,實在不太靈活。
隨著項目規(guī)模的擴大,管理大量的cron任務和它們的配置文件可能會變得復雜且容易出錯。特別是在多環(huán)境部署的情況下,維護一致性和同步配置文件需要額外的工作。
由于cron任務的執(zhí)行時間和頻率是預定義的,當任務執(zhí)行出現(xiàn)問題時,調(diào)試和跟蹤可能會比較困難。特別是當任務依賴于外部系統(tǒng)或資源時,問題定位和解決會更加復雜。頻繁修改cron配置文件可能會引入安全風險,尤其是在多用戶環(huán)境中。不當?shù)臋?quán)限管理或配置錯誤可能會導致任務被惡意利用或執(zhí)行不適當?shù)牟僮鳌?/p>
Cron Scheduler
PHP Cron Scheduler 是一個與框架無關(guān)的cron作業(yè)調(diào)度程序,可以輕松地與您的項目集成或作為獨立的命令調(diào)度程序運行。在使用這個任務調(diào)度器時,你只需要在你的服務器上創(chuàng)建單個 scheduler.php 入口。你的任務調(diào)度在scheduler.php方法中進行定義。
安裝
composer require peppeocchi/php-cron-scheduler開源地址:https://github.com/peppeocchi/php-cron-scheduler
如何工作
在項目根目錄下創(chuàng)建一個包含以下內(nèi)容的 scheduler.php 文件。
<?php
require_once __DIR__.'/vendor/autoload.php';
use GO\Scheduler;
// Create a new scheduler
$scheduler = new Scheduler();
// ... configure the scheduled jobs (see below) ...
// Let the scheduler execute jobs which are due.
$scheduler->run();然后在crontab中添加一個新條目,以便每分鐘運行 scheduler.php 。
* * * * * /usr/local/php-8.4/bin/php /home/tinywan/demo/scheduler.php 1>> /dev/null 2>&1就是這樣!您的調(diào)度程序已經(jīng)啟動并運行,現(xiàn)在您可以添加您的作業(yè),而無需再擔心crontab。這個Cron每分鐘都會調(diào)用scheduler.php命令調(diào)度器。然后評估你的計劃任務并運行到期的任務。
調(diào)度作業(yè)
默認情況下,您的所有作業(yè)將嘗試在后臺運行。PHP腳本和原始命令默認情況下將在后臺運行,而函數(shù)將始終在前臺運行。您可以通過調(diào)用 inForeground() 方法強制命令在前臺運行。必須將輸出發(fā)送到電子郵件的作業(yè)將在前臺運行。
執(zhí)行一個PHP腳本
$scheduler->php('path/to/my/script.php');計劃執(zhí)行時間
有幾種方法可以幫助您設置計劃的執(zhí)行時間。如果您不調(diào)用此方法中的任何一個,則作業(yè)將每分鐘(*)運行一次。
任何表達式
at -此方法接受dragonmantank/cron-expression支持的任何表達式
$scheduler->php('script.php')->at('* * * * *');每分鐘執(zhí)行
everyMinute 每分鐘執(zhí)行。您可以選擇傳遞 $minute 以指定作業(yè)每 $minute 分鐘運行一次。
$scheduler->php('script.php')->everyMinute();
$scheduler->php('script.php')->everyMinute(5);每小時運行
hourly 每小時運行一次。您可以選擇傳遞您想要運行的 $minute ,默認情況下,它將在每小時的'00'分鐘運行。
$scheduler->php('script.php')->hourly();
$scheduler->php('script.php')->hourly(53);每天運行
daily 每天運行一次。您可以選擇傳遞 $hour 和 $minute 以獲得更細粒度的控制(或字符串 hour:minute )
$scheduler->php('script.php')->daily();
$scheduler->php('script.php')->daily(22, 03);
$scheduler->php('script.php')->daily('22:03');最佳實踐
項目根目錄 scheduler.php 文件參考
<?php
declare(strict_types=1);
namespace think;
date_default_timezone_set('PRC');
require __DIR__ . '/vendor/autoload.php';
# PHP 二進制文件路徑
$bin = '/usr/local/php-8.4/bin/php';
$script = __DIR__ . '/think';
$scheduler = new \GO\Scheduler();
# 2024年7月16日 @add Tinywan 執(zhí)行一個Linux命令
$scheduler->raw('ps aux | grep nginx');
# 2024年7月10日 @add Tinywan 訂單自動取消 每1分鐘執(zhí)行一次
$scheduler->php($script . ' order cancel', $bin)->everyMinute(5);
$scheduler->run();執(zhí)行結(jié)果
[2024-07-28T00:10:02+08:00][info] 定時任務-商品推廣關(guān)閉 end
[2024-07-28T00:11:02+08:00][info] 定時任務-賬戶統(tǒng)計 end
[2024-07-28T00:12:02+08:00][info] 定時任務-賬戶統(tǒng)計 end
[2024-07-28T00:13:01+08:00][info] 定時任務-賬戶統(tǒng)計 end
[2024-07-28T00:14:02+08:00][info] 定時任務-賬戶統(tǒng)計 end
[2024-07-28T00:15:02+08:00][info] 定時任務-商品推廣關(guān)閉 start
[2024-07-28T00:15:02+08:00][info] 定時任務-訂單 start
[2024-07-28T00:15:02+08:00][info] 定時任務-賬戶統(tǒng)計 end小結(jié)
本文將探討如何在PHP環(huán)境下實現(xiàn)這種動態(tài)定時任務,旨在提供一個更加靈活、安全且易于管理的定時任務執(zhí)行機制。這將極大地提升項目的可擴展性和運維效率。




























