新手本地开发首选 database 驱动,仅需已有的数据库连接,无需额外安装服务或扩展;但上线前必须切换为 Redis 或 Supervisor 管理的 Horizon,否则高并发下表锁和轮询会导致消费延迟。

队列驱动选 database 还是 redis?
新手直接上 redis 容易卡在环境没装、扩展没启、配置写错三连——本地开发用 database 最省事,它只依赖你已有的数据库连接,不用额外装服务或 PHP 扩展。
但别长期留着:一旦并发稍高,database 驱动会因表锁和轮询拖慢整个队列消费,上线前必须切到 redis 或 supervisor 管理的 horizon。
-
QUEUE_CONNECTION=database就够,无需改.env里其他队列相关项 - 运行
php artisan queue:table再migrate,否则抛错Base table or view not found: 1146 Table 'xxx.jobs' doesn't exist -
redis驱动要确认phpredis扩展已启用(不是predis),且REDIS_HOST和REDIS_PASSWORD值正确,空密码也要显式写成REDIS_PASSWORD=null
php artisan queue:work 启不起来?看这三处
最常见不是命令输错,而是 Laravel 没意识到你在“跑队列”——它默认把队列当同步任务执行,除非你明确告诉它“现在要异步”。
- 发任务时必须用
dispatch()而非dispatchNow(),后者绕过队列直奔执行 -
.env里QUEUE_CONNECTION必须设为实际启用的驱动名(如database),不能是sync(那是假异步) - 运行命令前先清缓存:
php artisan config:clear,否则改了.env也读不到新值
如果仍卡住不动,加 --verbose 参数看真实报错,常是数据库连接失败或 Redis 连不上,而不是队列本身的问题。
任务类里 __construct 传参失败?序列化限制很具体
Laravel 队列任务必须能被 PHP 序列化,这意味着构造函数里只能传简单类型(字符串、数字、数组)或实现了 SerializesModels 的 Eloquent 模型。
- 别传
Request、Response、闭包、未实现Serializable的自定义对象 - 模型传 ID 更稳:
new SendEmailJob($user->id),进handle()再查库,避免模型延迟加载失效 - 如果必须传复杂数据,先
json_encode成字符串,进任务再json_decode,比硬扛序列化异常更可控
为什么 queue:work 一关就停?后台运行要绕开 Laravel 自带守护
php artisan queue:work 是前台进程,终端关掉就终止——这不是 bug,是设计如此。生产环境不能靠它扛流量。
- 本地测试可加
--once手动触发单次消费,避免常驻进程干扰调试 - Linux 生产环境用
supervisor管理进程,配置里autostart=true和autorestart=true是刚需 - 别信 “加
&放后台” 或nohup,它们不处理进程崩溃、日志轮转、内存泄漏,迟早出事
真正麻烦的是 Horizon——它本身依赖 Redis,且配置文件 config/horizon.php 里的 environments 键必须和当前 APP_ENV 完全匹配,少个字母都启动不了。










