laravel上线前需配置队列与定时任务:queue_connection设为database或redis,database需迁移jobs表,redis需确保配置一致;任务类须实现shouldqueue,构造函数只传基础类型;用dispatch()分发任务,生产环境用supervisor守护worker;定时任务通过schedule:run触发。

在Laravel项目上线前,必须让队列能稳定消费任务、定时任务能准时触发,否则异步邮件、数据清理、报表生成等功能将全部失效。
配置队列驱动并验证连接
打开 .env 文件,将 QUEUE_CONNECTION 改为 database 或 redis;若填成数据库名(如 myapp_db)会导致 queue:work 启动即报错或静默失败。
使用 database 驱动时,先执行迁移命令创建 jobs 表:php artisan queue:table → php artisan migrate。
使用 redis 驱动时,确认已运行 composer require predis/predis:^1.0,并检查 config/database.php 中 redis.default 的 host、port、password 与 .env 中 REDIS_HOST、REDIS_PORT、REDIS_PASSWORD 完全一致;【不一致会导致 Connection refused 错误,且 queue:work 不会提示具体哪项错】
创建可执行的队列任务类
运行命令生成任务骨架:php artisan make:job ProcessOrderNotification。
编辑 app/Jobs/ProcessOrderNotification.php,在类声明后手动添加 implements ShouldQueue;Laravel 9+ 不再默认实现,漏写会导致 dispatch() 同步执行,失去队列意义。
构造函数中只传 $orderId 这类基础类型或模型 ID,不要传 Request、Auth::user() 或 DB 实例——这些对象无法序列化,入队时直接抛出 Serialization of 'Closure' is not allowed。
在 handle() 方法里用 Order::findOrFail($this->orderId) 拉取数据,避免模型实例被序列化失败。
分发任务并指定执行策略
方法一:立即入队
在控制器中调用 ProcessOrderNotification::dispatch(123)。
方法二:延迟10分钟执行
ProcessOrderNotification::dispatch(123)->delay(now()->addMinutes(10))。
方法三:投递到 high 优先级队列
ProcessOrderNotification::dispatch(123)->onQueue('high');需确保 config/queue.php 中 default 队列名与之匹配,否则任务会被丢弃。
启动常驻队列监听器
第一步:本地调试时运行 php artisan queue:work --verbose 查看实时日志,加 --once 只处理一个任务后退出,方便验证逻辑是否正常。
第二步:生产环境必须用 Supervisor 管理进程,否则 SSH 断开后 worker 立即终止;配置中需设 autostart=true、autorestart=true、numprocs=3。
第三步:修改 config/queue.php 中 retry_after 值(默认90秒),确保它大于任务最长执行时间;若设为60但任务实际耗时80秒,该任务会被重复执行两次。
配置定时任务触发队列作业
在 app/Console/Kernel.php 的 schedule() 方法中添加:$schedule->job(new ProcessOrderNotification(456))->dailyAt('02:00');注意这里 new 的是任务实例,不是类名字符串。
在服务器上添加系统级 Cron 条目:* * * * * cd /var/www/myapp && php artisan schedule:run >> /dev/null 2>&1。
执行 php artisan schedule:list 可查看所有注册的调度任务及其下次运行时间,确认 dailyAt('02:00') 是否已生效。











