queue_connection改了仍同步执行,根本原因是配置未刷新:必须运行php artisan config:clear(开发)或config:cache(生产),否则laravel读取缓存旧配置,默认sync;验证用tinker执行config('queue.default')应返回redis等非sync值。

QUEUE_CONNECTION 改了但任务还是同步执行
这是最常踩的坑:改完 .env 里的 QUEUE_CONNECTION=redis,php artisan queue:work 却依然立刻执行任务,毫无异步感。
根本原因不是驱动没配对,而是 Laravel 没读到新配置——它默认读的是缓存后的 config,不是实时解析的 .env。
- 开发环境必须运行
php artisan config:clear,否则永远走旧缓存里的sync - 生产环境要用
php artisan config:cache(注意:改完.env后再跑) - 验证是否生效:进
php artisan tinker,执行config('queue.default'),返回值必须是你设的驱动名,比如"redis",不是"sync" - 别混淆
QUEUE_DRIVER(Laravel 5.7 以前)和QUEUE_CONNECTION(5.7+),新版只认后者
database 驱动报 “Base table or view not found: 1146 Table 'xxx.jobs'”
这不是配置错,是表压根没建。database 驱动依赖三张表:jobs、failed_jobs、job_batches(Laravel 9+ 才有),缺一不可。
- 先执行
php artisan queue:table生成jobs表迁移 - 再执行
php artisan queue:failed-table和php artisan queue:batches-table(如果项目用了批量任务) - 最后统一运行
php artisan migrate;已上线项目慎用migrate:fresh,可用php artisan migrate --path=database/migrations/2026_01_01_000000_create_jobs_table.php单独跑 - 确认
config/queue.php中connections.database.table值是'jobs'(默认值),别手误改成别的表名
redis 驱动连不上,queue:work 一直 idle
Redis 连接失败时,Laravel 不报错,只默默跳过——你看到的 “idle” 很可能就是连接被拒绝后静默退出的表现。
- 检查
REDIS_HOST和REDIS_PORT:Docker 环境下localhost指宿主机,得填容器名如redis -
QUEUE_CONNECTION=redis时,Laravel 只读REDIS_*系列变量(REDIS_HOST、REDIS_PASSWORD等),不看QUEUE_HOST这类命名 - Redis 有密码?必须设
REDIS_PASSWORD,且 Laravel 7+ 要求REDIS_URL格式为redis://:password@host:port,否则连接被拒也不提示 - 验证连接最直接:进
tinker,执行Redis::ping(),能回"PONG"才算通
任务 dispatch 了但 Redis 或数据库里完全没数据
不是驱动或连接问题,是任务类本身没达标——Laravel 对“可入队任务”有硬性要求。
- 任务类必须
implements ShouldQueue,php artisan make:job默认带,但手写类或从旧项目拷贝容易漏掉 - 构造函数里不能传入无法序列化的对象,比如
Request实例、Illuminate\Http\UploadedFile、DB 连接或闭包 - 别在
__construct里做耗时操作(如Mail::raw()、Storage::put()),这些必须挪到handle()方法里 - 确保调用的是
SendEmail::dispatch(),不是dispatch(new SendEmail())的老写法(虽兼容但易出错)
队列不是魔法开关,它是链式依赖:驱动要通、配置要清、任务要合规、worker 要常驻——少一环,任务就卡在半路,既不失败也不执行。











