Laravel如何针对不同任务配置多个队列驱动?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1031个文字,预计阅读时间需要5分钟。
Laravel 在运行时禁止动态注册新驱动。所有驱动都必须在 `connections` 数组中声明。你不是在切换驱动,而是在为不同任务指定使用哪个已配置的连接。
常见错误是只改 default 值,以为能全局切驱动;结果所有任务还是走同一个连接,只是名字变了。
-
config/queue.php的connections下定义多个键,比如'redis-high'、'database-low'、'sqs-critical' - 每个连接可指向不同
driver(redis、database、sqs),也可同驱动但不同配置(如 Redis 的不同 DB 或不同连接池) - 别漏掉
queue字段:它决定该连接默认投递到哪个队列名(如'high'、'low'),后续调度靠这个区分优先级
任务类里怎么指定用哪个队列连接
不是靠中间件或全局配置,而是任务类自身决定——通过 onConnection() 和 onQueue() 链式调用,或者直接在类里设属性。
容易踩的坑:在 handle() 里调用 dispatch() 新任务时,新任务不会继承当前连接,必须显式指定,否则走默认连接。
- 发任务时指定:
ProcessPayment::dispatch()->onConnection('redis-high')->onQueue('high') - 或在任务类里写:
public $connection = 'sqs-critical'; public $queue = 'critical'; - 使用
Bus::dispatchToQueue()时,第二个参数是连接名,第三个是队列名,别传反
Supervisor 怎么监听多个队列连接
Supervisor 本身不理解 Laravel 的“连接”,它只管执行 php artisan queue:work 命令。要跑多个驱动,就得启多个 worker 进程,每个绑定一个连接和队列。
典型错误是只配一个 command=php artisan queue:work,结果所有任务挤在默认连接里,高优任务被低优任务拖慢。
- 每个 Supervisor program 对应一条命令,例如:
command=php /var/www/artisan queue:work redis-high --queue=high --sleep=3 -
--queue参数值必须和任务投递时的$queue匹配(如high),不是连接名 - Redis 驱动下,
--tries和--timeout建议按任务类型分别设置,耗时任务别用默认 60 秒超时
数据库驱动队列和 Redis 驱动混用要注意什么
能混,但行为差异大:数据库驱动靠轮询,延迟高、吞吐低,适合低频后台任务;Redis 驱动是推送式,响应快,适合实时性要求高的场景。混用时最常出问题的是失败任务处理逻辑不一致。
比如你在 database 连接上设置了 retry_after = 90,但没同步更新对应表的 failed_jobs 表结构(Laravel 9+ 要求 uuid 字段),就会静默丢任务。
- 不同驱动的
retry_after含义不同:Redis 是消息 TTL,Database 是记录锁过期时间,别直接照搬数值 - Redis 连接若启用
block_for,会阻塞等待新任务,而 database 驱动永远要 sleep,别在高并发场景给 database 连接配block_for - 所有驱动共用同一张
failed_jobs表,但只有database和redis(需开启failed配置)能自动写入;SQS 等外部驱动得自己实现失败回调
本文共计1031个文字,预计阅读时间需要5分钟。
Laravel 在运行时禁止动态注册新驱动。所有驱动都必须在 `connections` 数组中声明。你不是在切换驱动,而是在为不同任务指定使用哪个已配置的连接。
常见错误是只改 default 值,以为能全局切驱动;结果所有任务还是走同一个连接,只是名字变了。
-
config/queue.php的connections下定义多个键,比如'redis-high'、'database-low'、'sqs-critical' - 每个连接可指向不同
driver(redis、database、sqs),也可同驱动但不同配置(如 Redis 的不同 DB 或不同连接池) - 别漏掉
queue字段:它决定该连接默认投递到哪个队列名(如'high'、'low'),后续调度靠这个区分优先级
任务类里怎么指定用哪个队列连接
不是靠中间件或全局配置,而是任务类自身决定——通过 onConnection() 和 onQueue() 链式调用,或者直接在类里设属性。
容易踩的坑:在 handle() 里调用 dispatch() 新任务时,新任务不会继承当前连接,必须显式指定,否则走默认连接。
- 发任务时指定:
ProcessPayment::dispatch()->onConnection('redis-high')->onQueue('high') - 或在任务类里写:
public $connection = 'sqs-critical'; public $queue = 'critical'; - 使用
Bus::dispatchToQueue()时,第二个参数是连接名,第三个是队列名,别传反
Supervisor 怎么监听多个队列连接
Supervisor 本身不理解 Laravel 的“连接”,它只管执行 php artisan queue:work 命令。要跑多个驱动,就得启多个 worker 进程,每个绑定一个连接和队列。
典型错误是只配一个 command=php artisan queue:work,结果所有任务挤在默认连接里,高优任务被低优任务拖慢。
- 每个 Supervisor program 对应一条命令,例如:
command=php /var/www/artisan queue:work redis-high --queue=high --sleep=3 -
--queue参数值必须和任务投递时的$queue匹配(如high),不是连接名 - Redis 驱动下,
--tries和--timeout建议按任务类型分别设置,耗时任务别用默认 60 秒超时
数据库驱动队列和 Redis 驱动混用要注意什么
能混,但行为差异大:数据库驱动靠轮询,延迟高、吞吐低,适合低频后台任务;Redis 驱动是推送式,响应快,适合实时性要求高的场景。混用时最常出问题的是失败任务处理逻辑不一致。
比如你在 database 连接上设置了 retry_after = 90,但没同步更新对应表的 failed_jobs 表结构(Laravel 9+ 要求 uuid 字段),就会静默丢任务。
- 不同驱动的
retry_after含义不同:Redis 是消息 TTL,Database 是记录锁过期时间,别直接照搬数值 - Redis 连接若启用
block_for,会阻塞等待新任务,而 database 驱动永远要 sleep,别在高并发场景给 database 连接配block_for - 所有驱动共用同一张
failed_jobs表,但只有database和redis(需开启failed配置)能自动写入;SQS 等外部驱动得自己实现失败回调

