用 php-cron-scheduler 管理 PHP 定时任务

用 php-cron-scheduler 在 PHP 应用内实现定时任务:调度脚本、闭包与命令,自定义执行时间、前置条件、前后钩子与输出落盘,框架无关可独立运行。本文从安装到监控全覆盖。

最佳实践
应用程序模块协作插画

本文依据官方文档整理,未执行运行验证或性能基准。代码片段展示局部用法,业务函数、数据和环境需按项目补齐;版本与配置以所引文档为准。

直接回答:PHP 做定时任务的两条主流路径——框架外用 php-cron-scheduler 包(框架无关,可独立运行),Laravel 项目用内置调度器。系统 cron 每分钟触发入口脚本,任务定义全在 PHP 代码里:脚本、闭包、Shell 命令均可调度,支持执行条件、前后钩子与输出重定向。

安装

mkdir phpCronDemo && cd phpCronDemo
composer require peppeocchi/php-cron-scheduler

调度第一个任务

<?php
require __DIR__ . '/vendor/autoload.php';
use GO\Scheduler;

$scheduler = new Scheduler();
$scheduler->php(__DIR__ . '/backup.php')->daily();              // 调度 PHP 脚本
$scheduler->call(fn() => cleanup())->everyMinute();  // 调度闭包
$scheduler->raw('/usr/local/bin/backup-app-db')->hourly(); // 项目中已有的受控备份脚本
$scheduler->run();

此处 cleanup() 和 backup-app-db 是项目自定义实现,需先准备。备份使用最小权限数据库账号、受保护的凭据文件及输出目录,不能把用户输入拼入 raw 命令。系统 cron 每分钟触发入口:

* * * * * php /path/to/scheduler.php >> /var/log/app-scheduler.log 2>&1

执行时间、条件与钩子

  • 时间:daily('14:30') 指定每日时刻,at('*/10 * * * *') 接收 cron 表达式;不要混用 Laravel 的 dailyAt/cron API
  • 条件:->when(fn() => date('N') <= 5) 只在工作日跑
  • 钩子:->before() 前置准备、->then() 后置处理、运行后读取 getFailedJobs() 检查失败;不能照搬 Laravel 的 onFailure API
  • 输出落盘:->output('/var/log/job.log') 留档排障

监控这一环不能省

定时任务的经典翻车是静默失效——cron 被注释、进程内存超限被杀、依赖服务挂了,全都"安静地不发生"。没有监控的任务调度等于裸奔。

任务日志至少保留任务名、计划时间、开始和结束时间及结果。若接入观测云,用 DataKit采集这些记录,再按任务实际周期设置检测规则;验证时分别模拟任务失败、任务未启动和采集停止,确认“没有成功记录”能引导值班人员继续区分原因。

常见问题(FAQ)

Q:php-cron-scheduler 和 Laravel 调度器怎么选?
A:Laravel 项目直接用内置调度器(生态集成更深);非 Laravel 项目或独立脚本集用 php-cron-scheduler。

Q:任务时间漂移怎么办?
A:系统 cron 是分钟粒度,且依赖触发时刻机器的负载。at() 只定义计划表达式,不能消除机器负载造成的延迟;需要记录实际开始时间、避免长同步任务阻塞,并监控调度偏差。

Q:多台服务器怎么避免重复执行?
A:包本身无分布式锁——用 Redis/数据库锁自行实现,或只在一台指定机器上跑调度入口。

官方参考

资料核对日期:2026-09-29。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台