laravel 11任务调度本身不支持超时控制,超时由队列系统实现;需在任务类设$timeout属性、调度时用timeout()覆盖,或配置worker参数及retry_after匹配。

Laravel 11 的任务调度本身不直接支持超时控制,它只负责“何时触发任务”,而超时机制由底层队列系统承担。也就是说,调度任务(Schedule)的超时,本质是它所分发的队列任务(Job)的超时。你需要在任务类、分发过程或队列 worker 启动时配置,而非在 $schedule 链式调用里设 timeout。
在任务类中声明 $timeout 属性
这是最常用、最清晰的方式。Laravel 会自动识别该属性,并在任务执行超过设定秒数时终止进程:
- 打开你的任务类,例如
App\Jobs\ProcessData.php - 添加 protected 属性:
protected $timeout = 180;(表示最多运行 3 分钟) - 该值对所有通过该类分发的任务生效,包括被调度器调用的场景
调度时动态指定超时(覆盖类中定义)
如果你希望同一任务类在不同调度场景下使用不同超时策略,可在 app/Console/Kernel.php 的 schedule 方法中,用 timeout() 显式覆盖:
$schedule->job(new ProcessData)->daily()->timeout(300);- 这等价于
ProcessData::dispatch()->timeout(300),优先级高于类中$timeout - 注意:仅适用于使用
job()或call()调度队列任务,不适用于闭包调度
确保队列驱动与 retry_after 匹配
超时要真正生效,必须配合正确的队列驱动和配置:
- 生产环境禁用
sync驱动——它会忽略所有 timeout,任务同步阻塞请求 - .env 中设
QUEUE_CONNECTION=redis(或database、sqs) - 在
config/queue.php中,对应连接的retry_after值必须 ≥ timeout,建议多留 10–30 秒缓冲。例如:'retry_after' => 210对应$timeout = 180
补充:防止隐性超时的 worker 运行参数
即使单任务有 timeout,长期运行的 worker 进程仍可能因内存泄漏或累积引用变慢。上线时务必加防护:
-
--memory=128:内存超限自动退出 -
--max-jobs=500:处理 500 个任务后重启,释放静态变量等资源 -
--max-time=3600:强制每小时重启一次,切断潜在泄漏链 - 这些参数需写入 Supervisor 配置,确保 worker 异常退出后能自动拉起











