Laravel 队列入门全攻略:从基础到实战

Laravel 队列(Queue)是处理耗时任务的强大工具,比如邮件发送、图片处理、API 请求、定时任务等。如果你还在同步执行这些操作,导致用户等待时间长,那一定要学会 Laravel 队列。

本文会手把手带你入门 Laravel 队列,包括基本概念、驱动配置、任务创建、队列监听、错误处理,让你从 0 到 1 熟练使用 Laravel 队列。

1. 为什么要用 Laravel 队列?

假设你的应用有以下需求:

用户注册时发送邮件 (同步发送会卡住页面)

订单支付后通知供应商 (外部 API 请求慢)

用户上传图片后生成缩略图 (图片处理很耗时)

定期清理数据库、发送定时通知(后台任务)

如果你把这些任务同步执行 ,用户必须等所有操作完成,体验会很差。
解决方案 :使用 Laravel 队列,让这些任务异步执行,不阻塞主线程,提高应用响应速度!

2. Laravel 队列基本概念

Laravel 队列的核心流程:

1️⃣ 创建 Job(任务) :定义具体要执行的代码逻辑

2️⃣ 分发 Job 到队列 :使用 dispatch() 把任务推到队列中

3️⃣ 队列驱动 :存储队列任务的数据(Redis、Database等)

4️⃣ 队列监听器:从队列取出任务,执行并删除

3. 配置 Laravel 队列

Laravel 默认使用 sync(同步执行),需要手动改成队列模式。

3.1 选择队列驱动

Laravel 目前支持的队列驱动:

database ------ 使用 MySQL 存储任务(适合小项目)

redis ------ 高性能,推荐生产环境使用

beanstalkd ------ 高效消息队列(需要额外安装)

sqs ------ Amazon SQS

3.2 配置 .env

ini 复制代码
ini
复制编辑
QUEUE_CONNECTION=redis  # 使用 Redis 作为队列驱动

然后在 config/queue.php 里修改:

bash 复制代码
php
复制编辑
'default' => env('QUEUE_CONNECTION', 'redis'),

📌 推荐使用 Redis,因为它性能好,支持延迟队列和失败任务重试。

4. 创建 Laravel 队列任务(Job)

Laravel 提供了 make:job 命令来创建任务:

go 复制代码
bash
复制编辑
php artisan make:job SendEmailJob

app/Jobs/SendEmailJob.php 里,Laravel 自动生成了 handle() 方法,我们在这里编写具体任务逻辑。

php 复制代码
php
复制编辑
namespace App\Jobs;

use Mail;
use App\Models\User;
use App\Mail\WelcomeEmail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class SendEmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $user;

    // 任务构造函数,接收参数
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    // 任务执行逻辑
    public function handle()
    {
        Mail::to($this->user->email)->send(new WelcomeEmail($this->user));
    }
}

📌 这个任务会给用户发送邮件,但不会同步执行,而是加入队列,后台运行。

5. 任务推送到队列

在控制器里,我们可以用 dispatch() 把任务加入队列:

ini 复制代码
php
复制编辑
use App\Jobs\SendEmailJob;
use App\Models\User;

$user = User::find(1);
dispatch(new SendEmailJob($user));

或者使用 延迟执行

scss 复制代码
php
复制编辑
dispatch(new SendEmailJob($user))->delay(now()->addMinutes(5));

📌 任务不会立即执行,而是进入 Redis / Database 队列,后台执行!

6. 启动 Laravel 队列监听器

队列任务进入队列后,需要有个"工人"来执行它们。Laravel 提供了 queue:work 命令来监听队列:

arduino 复制代码
bash
复制编辑
php artisan queue:work

这个命令会不断监听队列,一旦有新任务,就会立即执行。

6.1 让队列一直运行

Laravel 队列默认执行一次后就退出,为了让它持续运行,我们可以用 --daemon 选项:

arduino 复制代码
bash
复制编辑
php artisan queue:work --daemon

但这个方法不够稳妥,推荐使用 Supervisor 来守护进程。

6.2 生产环境用 Supervisor 监听队列

在 Ubuntu 服务器上安装 Supervisor:

复制代码
bash
复制编辑
sudo apt install supervisor

然后创建 queue-worker.conf

ini 复制代码
ini
复制编辑
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /path/to/artisan queue:work --tries=3
autostart=true
autorestart=true
numprocs=1
redirect_stderr=true
stdout_logfile=/var/log/laravel-worker.log

启动 Supervisor:

sql 复制代码
bash
复制编辑
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*

📌 这样就可以让 Laravel 队列进程一直运行,即使服务器重启也不会中断!

7. 处理失败任务

如果任务执行失败,Laravel 会自动重试 3 次(默认值,可在 queue:work --tries=5 设置)。

如果任务还是失败,可以用以下命令检查失败队列:

arduino 复制代码
bash
复制编辑
php artisan queue:failed

然后重新执行失败任务:

arduino 复制代码
bash
复制编辑
php artisan queue:retry all

或者删除失败任务:

arduino 复制代码
bash
复制编辑
php artisan queue:flush

📌 生产环境下,一定要用 Redis 作为队列,并配置 Supervisor 监控,防止任务丢失!

8. 进阶用法

8.1 指定队列名称

可以在 dispatch() 时指定任务进入特定队列:

scss 复制代码
php
复制编辑
dispatch(new SendEmailJob($user))->onQueue('emails');

然后启动监听指定队列:

arduino 复制代码
bash
复制编辑
php artisan queue:work --queue=emails

8.2 任务唯一性

有些任务不希望重复执行,比如避免重复发送邮件:

kotlin 复制代码
php
复制编辑
class SendEmailJob implements ShouldQueue, ShouldBeUnique

这样即使多次 dispatch 这个任务,Laravel 也会只执行一次。

总结

步骤 操作
1. 选择队列驱动 配置 .env 选择 databaseredis
2. 创建任务 php artisan make:job TaskName
3. 推送任务 dispatch(new TaskName($param))
4. 监听队列 php artisan queue:work
5. 失败任务管理 queue:failed, queue:retry
6. 生产环境优化 用 Redis + Supervisor 守护进程

Laravel 队列让异步任务变得简单易用,提高性能的同时还能减少页面等待时间。你可以用它来优化邮件发送、数据处理、定时任务等各种耗时操作。

现在,你可以尝试在项目里加上 Laravel 队列,看看是否能提升响应速度!赶紧去试试吧!

相关推荐
tianlebest1 天前
Laravel 安全:批量赋值 fillable 与 guarded
数据库·安全·laravel
深山技术宅3 天前
在Laravel 12中实现基于parent_id的树状数组
php·laravel
深山技术宅5 天前
在 Laravel 12 中实现 WebSocket 通信
websocket·php·laravel
深山技术宅5 天前
laravel 12 监听syslog消息,并将消息格式化后存入mongodb
mongodb·php·laravel
深山技术宅9 天前
Laravel 12 实现 API 登录令牌认证
php·laravel
深山技术宅9 天前
Laravel 12 实现 OAuth2 登录
php·laravel
Taichi呀9 天前
Laravel+API 接口
php·laravel
Taichi呀12 天前
Laravel基础
php·laravel
foryoufeng15 天前
Laravel代码生成器,快速构建项目代码,统一团队编码风格
php·laravel
奔跑的皮皮虾19 天前
Laravel 对接阿里云 OSS 说明文档
阿里云·php·laravel