Laravel 5.5 Cron任务调度问题:命令handle函数未自动调用
我来帮你一步步排查这个问题,从最常见的原因开始梳理:
第一步:先手动测试命令是否能正常运行
首先排除命令本身的问题,在项目根目录的终端里执行:
php artisan SendNotification:LoginTrack
然后查看Laravel日志文件(storage/logs/laravel.log):
- 如果能看到
hi from send notification handle这条日志,说明命令本身逻辑没问题,问题出在系统Cron调度配置上; - 如果看不到这条日志,那先解决命令注册的问题。
如果手动执行命令无效(命令本身有问题)
1. 修正命令注册的写法
在Kernel.php的$commands数组里,推荐使用类常量::class来引用命令,避免字符串拼写错误:
protected $commands = [ \App\Console\Commands\SendNotificationLoginTrack::class, ];
这种写法能让IDE帮你校验类是否存在,比纯字符串更可靠。
2. 刷新命令缓存
执行以下命令清除Laravel的缓存并重新加载命令列表:
php artisan optimize:clear composer dump-autoload
如果手动执行有效,但调度任务不触发
这说明问题出在系统Cron的配置上——Laravel的任务调度依赖系统Cron每分钟调用一次schedule:run命令,这是很多人容易忽略的核心步骤。
1. 配置系统Cron任务
登录你的服务器,编辑Cron任务列表:
crontab -e
添加以下一行(替换/path/to/your/project为你项目的实际根目录,比如/var/www/html/your-laravel-app):
* * * * * php /path/to/your/project/artisan schedule:run >> /dev/null 2>&1
这条命令的作用是:每分钟执行一次Laravel调度器,把输出重定向到空设备避免日志堆积。
2. 确认Cron的PHP路径正确
有时候Cron的环境变量和终端不一致,php命令的路径可能不同。先在终端执行which php获取PHP的绝对路径(比如/usr/bin/php),然后把Cron命令里的php替换成这个绝对路径:
* * * * * /usr/bin/php /path/to/your/project/artisan schedule:run >> /dev/null 2>&1
3. 查看调度任务的执行日志
为了排查具体错误,可以给调度任务添加日志输出,修改Kernel.php的schedule方法:
$schedule->command('SendNotification:LoginTrack') ->everyMinute() ->appendOutputTo(storage_path('logs/schedule_command.log'));
这样每次调度执行命令时,输出会写入storage/logs/schedule_command.log,如果有错误(比如邮件发送失败、权限问题)会在这里显示。
4. 检查系统Cron日志
不同系统的Cron日志位置不同:
- Ubuntu/Debian:查看
/var/log/syslog,用grep CRON /var/log/syslog过滤Cron相关记录,看有没有任务执行的错误信息; - CentOS/RHEL:直接查看
/var/log/cron文件。
你提到构造函数里手动调用$this->handle()能正常执行,说明handle函数的业务逻辑是没问题的,问题肯定出在命令注册或者调度触发的环节,按照上面的步骤排查应该能解决。
内容的提问来源于stack exchange,提问作者Aamir Mir

