什么是队列
在 Web 应用中,发送邮件、缩放图片、请求外部 API 等操作可能耗时数秒。 若在 HTTP 请求中同步处理,用户必须等到响应返回才能继续。 Laravel 的队列可以让这类耗时操作在后台异步执行。 请求可以立即返回响应,实际处理由 worker 进程另行完成。队列支持数据库、Redis、Amazon SQS 等多种后端。
开发环境可以使用
sync 驱动,让任务不经队列直接执行。队列配置
config/queue.php
队列配置集中在config/queue.php。通过 QUEUE_CONNECTION 环境变量切换驱动。
.env 配置
准备数据库驱动
使用database 驱动需要保存任务的表。Laravel 11 及以上的新项目默认包含相应迁移,未包含时可运行:
准备 Redis 驱动
使用redis 驱动请在 config/database.php 配置 Redis 连接,并安装依赖:
SQS Overflow Storage
Amazon SQS 对单条消息大小有限制。若任务负载可能很大,可以将超过部分保存到缓存存储,SQS 中只放引用:- 启用
enabled后,大于 1MB 的负载会被写入指定缓存存储。 always为true时,无论大小都将 SQS 负载写入缓存。delete_after_processing在任务成功后删除已保存的负载(默认true)。flush_on_clear为true时,在queue:clear时会 flush overflow 缓存。为避免影响普通缓存,建议使用独立缓存存储。
创建任务类
make:job 命令
app/Jobs/SendWelcomeEmail.php。
任务类结构
ShouldQueue 告诉 Laravel 该任务要走队列异步处理。
Queueable trait 提供了必要的操作方法。
派发任务
dispatch()
在控制器或服务中派发任务:延迟派发
dispatchAfterResponse()
在 HTTP 响应返回之后立刻执行任务。sync 驱动也可用,适合无需专用 worker 的轻量场景。
指定队列
Queue Routing
在服务提供者boot() 中通过 Queue::route() 集中配置任务的默认连接 / 队列:
Queue Routing 可被任务自身的
onQueue() / onConnection() 覆盖。同步执行(测试 / 开发)
批量派发
使用Bus::bulk() 一次派发大量独立任务,无需追踪进度或回调:
Bus::bulk() 会按连接与队列名分组批量推送。与 Bus::batch() 不同,没有进度追踪与完成回调,适合大量独立任务的简单批量发送。处理任务
queue:work
启动 worker 处理任务:worker 常用选项
在任务类上写重试配置
任务释放(Release 中间件)
在特定条件下不执行任务而将其放回队列,可使用Release 中间件:
Release::unless() 则在条件为 false 时释放。
失败任务处理
准备 failed_jobs 表
任务超过最大重试次数会写入failed_jobs。若无此表:
失败时的清理
在任务类定义failed() 方法:
用异常控制不重试
某些异常无需重试。在bootstrap/app.php 的 withExceptions() 中用 dontRetry 指定:
dontRetryWhen,回调返回 true 时立即失败:
查看失败任务
重试失败任务
删除失败任务
常用驱动
database
无需额外中间件即可上手。任务存jobs 表,worker 轮询处理。
- 优点:配置简单,可复用 RDBMS
- 缺点:数据库压力大,不适合大量任务
redis
生产环境最常用,内存速度快,可支撑大量任务。- 优点:速度快、可扩展
- 缺点:需要 Redis 服务
使用 Supervisor 在生产环境运行
在 Linux 上通常使用 Supervisor 保证queue:work 崩溃后自动重启:
numprocs=2 表示并行启动 2 个 worker。之后:
实战示例:用队列处理邮件发送
1
生成任务类
2
实现任务
3
控制器中派发
4
启动 worker
小结
何时应使用队列
何时应使用队列
- 发送邮件 / SMS
- 图片、视频的缩放或转码
- 请求外部 API
- 生成报表或导出 CSV
- 发送 Webhook
开发小技巧
开发小技巧
在
.env 中设置 QUEUE_CONNECTION=sync,任务将立即执行、不经队列,无需启动 worker 就能调试。常用命令
常用命令