
本文详解 Laravel 队列的正确配置流程,涵盖驱动选择、表迁移、进程启动、常见陷阱(如 .env 中误填数据库名)及调试方法,助你快速定位“任务不入队、不执行”问题。
本文详解 laravel 队列的正确配置流程,涵盖驱动选择、表迁移、进程启动、常见陷阱(如 `.env` 中误填数据库名)及调试方法,助你快速定位“任务不入队、不执行”问题。
在 Laravel 中启用真正异步的任务处理,关键在于配置、分发与消费三个环节严格对齐。你遇到的“Job 不执行、jobs 表无记录、命令无输出”问题,绝大多数情况下源于配置层面的细微错误——尤其是 .env 文件中 QUEUE_CONNECTION 值的误写。
✅ 第一步:修正队列驱动配置(最常见错误!)
你的 .env 中写的是:
QUEUE_CONNECTION=database_name
这是根本性错误。QUEUE_CONNECTION 的值不是你的数据库名(如 laravel_app),而是 Laravel 预定义的驱动标识符,例如 database、redis、sqs 等。
✅ 正确写法(使用数据库驱动):
QUEUE_CONNECTION=database
⚠️ 注意:
- database 是 Laravel 内置的驱动名,对应 config/queue.php 中 connections.database 配置;
- 若你误写为 database_name,Laravel 会尝试查找名为 database_name 的连接,但该连接不存在 → 任务默认回退至 sync(同步)驱动 → 看似“执行了”,实则阻塞请求、不进队列、不写 jobs 表;
- 同理,Redis 驱动应写 QUEUE_CONNECTION=redis,而非 QUEUE_CONNECTION=my_redis。
验证是否生效:运行以下命令,确认输出的连接名与 .env 一致:
php artisan tinker
>>> config('queue.default')
// 应返回 "database"
>>> config('queue.connections.database.driver')
// 应返回 "database"✅ 第二步:确保队列表已正确创建并迁移
即使配置正确,若 jobs 表缺失,任务也无法持久化。
-
生成队列表迁移文件:
php artisan queue:table php artisan queue:failed-table # 推荐一并生成,便于排查失败任务
-
执行迁移:
php artisan migrate
✅ 检查数据库:确认 jobs 和 failed_jobs 表已存在,且结构符合 Laravel 要求(含 id, queue, payload, attempts, reserved_at, available_at, created_at 等字段)。
✅ 第三步:正确分发与监听任务
你的控制器代码基本正确,但可优化为更健壮的写法:
use App\Jobs\CheckSuscription;
class TestController extends Controller
{
public function index()
{
// 显式指定队列名(与 handle 中逻辑无关,仅影响优先级调度)
CheckSuscription::dispatch()->onQueue('processing');
// ✅ 可选:立即响应,避免用户等待
return response()->json(['status' => 'Job dispatched']);
}
}启动监听器时,请使用标准命令:
# 开发调试(前台运行,实时输出日志) php artisan queue:work --verbose --tries=3 # 或使用 listen(自动重启,适合开发,但不推荐生产) php artisan queue:listen --verbose
? 关键观察点:
- 成功入队后,jobs 表应立即新增一条记录(attempts=0, reserved_at=null, available_at ≤ now());
- 启动 queue:work 后,日志应出现 Processing jobs from the [processing] queue 和 Processed jobs from the [processing] queue;
- 若仍无任何输出,请检查 PHP 错误日志或 Laravel storage/logs/laravel.log,常见报错如 Connection refused(Redis 配置错误)、Class not found(Job 类命名空间错误)等。
⚠️ 常见陷阱与进阶建议
| 问题现象 | 原因 | 解决方案 |
|---|---|---|
| jobs 表为空,但控制器返回成功 | QUEUE_CONNECTION 配置错误 → 回退 sync 驱动 | 严格按 database/redis 等关键字填写,勿加下划线或数据库名 |
| 任务入表但不执行 | queue:work 进程未运行,或监听了错误队列 | 使用 php artisan queue:work --queue=processing 显式指定队列名 |
| 修改 Job 代码后任务仍执行旧逻辑 | queue:work 是常驻进程,不自动重载代码 | 部署后务必执行 php artisan queue:restart(优雅重启所有 worker) |
| 生产环境任务中断 | 终端关闭导致 queue:work 进程终止 | 必须使用 Supervisor / PM2 / Systemd 守护进程(示例见下文) |
? Supervisor 生产配置示例(/etc/supervisor/conf.d/laravel-worker.conf):
[program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /var/www/your-app/artisan queue:work --queue=processing,default --sleep=3 --tries=3 --max-time=3600 autostart=true autorestart=true user=www-data numprocs=8 redirect_stderr=true stdout_logfile=/var/www/your-app/storage/logs/worker.log
执行后重载:
sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start laravel-worker:*
✅ 总结:5 分钟快速排障清单
- ✅ 检查 .env:QUEUE_CONNECTION=database(非 database_name);
- ✅ 运行 php artisan config:clear 清除配置缓存;
- ✅ 执行 php artisan queue:table && php artisan migrate;
- ✅ 在控制器中调用 dispatch(),刷新页面;
- ✅ 查看 jobs 表是否有新记录 → 有则说明入队成功;
- ✅ 运行 php artisan queue:work --verbose → 观察控制台输出是否开始处理。
只要配置精准、步骤完整,Laravel 队列即可稳定支撑邮件发送、报表生成、第三方 API 调用等典型异步场景。记住:队列不是魔法,而是契约——配置即契约,驱动即协议,监听即履约。


















