本文目录导读:

Laravel 的任务调度不支持原生的秒级调度。
Laravel 的调度器 (schedule) 是基于 Cron 表达式的,标准的 Cron 表达式最小粒度是分钟,所以最低只能设置 ->everyMinute()(每分钟执行一次)。
如果你需要实现秒级的执行频率(例如每5秒、每30秒执行一次),需要通过以下变通方案实现:
使用 ->everyMinute() + 内部循环
最常用的方法,调度任务每分钟启动一次,然后在任务自身内部进行秒级循环。
示例:每10秒执行一次
-
在
Kernel.php中:protected function schedule(Schedule $schedule) { $schedule->job(new ProcessHighFequencyTasks)->everyMinute(); } -
在
ProcessHighFequencyTasksJob 中:<?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class ProcessHighFequencyTasks implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; public function handle() { $endTime = now()->addSeconds(60); // 运行59秒后停止,避免与下一次调度重叠 while (now()->lessThan($endTime)) { // 需要执行的逻辑 $this->doSomething(); // 等待 10 秒 sleep(10); // 注意:CLI 模式下 sleep 是安全的 // 或者用 usleep(10000000); // 微秒级等待 } } private function doSomething() { // 你的业务代码 } }
使用自定义 Artisan 命令 + 无限循环
在自定义命令中实现一个守护进程式的循环,然后由 supervisor 管理。
示例:
// app/Console/Commands/ProcessRealTime.php
class ProcessRealTime extends Command
{
protected $signature = 'app:process-real-time';
public function handle()
{
while (true) {
// 每5秒执行一次
$this->call('some:other-command');
sleep(5);
}
}
}
然后在 Kernel.php 中调用它,但通常不需要调度,而是用 Supervisor 直接监控这个命令:php artisan app:process-real-time。
使用事件循环库(如 ReactPHP)
对于超高频(毫秒级)或需要非阻塞 I/O 的场景,可以结合 ReactPHP:
$loop = React\EventLoop\Factory::create();
$loop->addPeriodicTimer(1, function () {
// 每秒执行一次
});
$loop->run();
⚠️ 重要注意事项
- 防止任务堆积:如果使用
->everyMinute()+ 内部循环,必须确保循环在下一次调度触发前结束,否则会导致进程数快速增长,最终耗尽服务器资源(内存泄漏或进程爆炸),上面的例子中设置了60秒超时(留1秒缓冲)。 - 使用队列:强烈建议将内部循环逻辑放入 Job 中并设置为
ShouldQueue,这样调度器只负责投递 Job,不会长时间占用 CLI 进程。 - 守护进程管理:如果使用无限循环方案,必须用
Supervisor或systemd来管理进程,确保进程崩溃后自动重启。 - 性能考量:秒级任务对数据库、缓存、外部 API 的调用频率很高,注意做好幂等性设计和限流。
| 需求 | 推荐方案 |
|---|---|
| 每5-59秒一次 | ->everyMinute() + 内部 sleep() 循环(最安全) |
| 持续执行且可秒级控制 | 自定义命令 + Supervisor 管理守护进程 |
| 需要高精度非阻塞调用 | 使用 ReactPHP 等事件循环库 |
不要直接尝试修改 Laravel 核心以支持秒级 Cron,因为操作系统层面的 Cron 本身就不支持秒级,强行绕过会导致不可预测的问题。