SSH 进服务器看 crontab 时,发现一堆被注释掉的行、指向已删除命令的入口、无人知晓的 3am 任务——这些都在单台机器上,不在 Git,不在部署流程,随自动伸缩消失。Symfony Scheduler 组件让定时任务变为版本化的 PHP 代码,随应用发布、接受代码审查、可单元测试。自 Symfony 6.4 稳定以来持续演进。
核心是一个实现ScheduleProviderInterface的类,用#[AsSchedule]标记。every()接受人类可读间隔(如'1 hour'),cron()使用标准 cron 表达式。消息是普通 DTO,无基类无接口。调度本身是 Messenger 传输层——到期的消息经同一总线、中间件、重试策略和失败传输处理。运行命令为php bin/console messenger:consume scheduler_main,生产环境用 Supervisor 或 systemd 管理,无需任何 crontab 行。
注意单进程锁陷阱:如果运行多个消费者,每个都会独立触发调度。安装symfony/lock组件并用共享存储(Redis、数据库)加锁,只有锁持有者生成消息。可选->stateful()配合缓存池记录上次运行,让恢复的 worker 能补发错过的触发。
可单元测试调度逻辑:通过getSchedule()->getRecurringMessages()获取消息,对getTrigger()->getNextRunDate()断言,在 CI 中捕获 cron 变更,而非在工单中调查。调度随部署和回滚同步,锁和状态保持在框架边缘,业务逻辑只关心消息 DTO。
#开发者 #工具 #Symfony #PHP #Cron #Messenger #Scheduler #单元测试
@DevToolboxHub

