认识队列

什么是队列?

不管是文档还是教程中都没有下定义。现在只是刚会用队列,要我下定义就更不可能了。还是等以后能熟练运用了再说吧。

队列的应用

1. 教程中的例子:利用百度翻译 api 翻译文章的标题。

2. 通过发送短信的 api 实现用户绑定手机号。

队列的作用:

文档原文:

通过队列,你可以将耗时任务 (如发送电子邮件) 的处理往后推延。延迟这些耗时的任务可以极大地提升 web 请求响应速度。

其实通过队列的应用也能总结出队列的作用。因为在使用第三方接口时可能会遇到的问题:

1. 由于某些原因,执行出错。

2. 增加请求响应的时间。

如果使用队列:

1. 可以异步执行消耗时间的任务,降低请求响应的时间。

2. 调用第三方 api 出错后可以重试。

使用队列的步骤

以给用户发送邮件为例(这个例子来源于laravel 队列之队列消息与发送邮件):

1. 配置队列

以 Redis 为例:

  • 安装依赖:

composer require "predis/predis:~1.1"
  • 修改 .env 文件

QUEUE_CONNECTION=redis

// 指定 predis 作为请求 Redis 的类库:

REDIS_CLIENT=predis

2. 生成任务类。

artisan 命令行:


php artisan make:job SendMailToUser

3. 任务类类结构。

这个生成的文件大概分2部分:

一是 __construct() 构造方法 ;

文档原文:

如果你的队列任务在其构造函数中接受一个 Eloquent 模型,那么只有模型的标识符才会被序列化到队列中。当实际处理任务时,队列系统将自动重新从数据库中获取完整的模型实例及其加载的关系。

在这个例子中,接收一个 User 模型。对上述原文不太理解,但是感觉在处理任务时,不仅能得到完整的实例还能获取该模型和其他模型的关系。现在也用不到,以后再回来补吧。

二是 handle 队列执行方法。当任务由队列处理时,将调用 handle 方法。在这里,当处理任务时,发送邮件给用户。


<?php

namespace App\Jobs;

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;

use Illuminate\Support\Facades\DB;

// 引入Mailer类。
use Illuminate\Contracts\Mail\Mailer;

use App\Models\User;

class SendMailToUser implements ShouldQueue

{

    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**

     * Create a new job instance.

     *

     * @return void

     */

    protected $user;

    public function __construct(User $user)

    {

        $this->user = $user;

    }

    /**

     * Execute the job.

     *

     * @return void

     */

    public function handle(Mailer $mailer)

    {

        // 发送邮件给用户。

        $user = $this->user;

        $mailer->send('emails.sendMail',['user'=>$user],function($message) use ($user){

            $message->to($user->email)->subject('队列测试!');

        });

    }

}

4. 分发队列。

当我访问TestsController的testQueue方法时,就分发队列:

先定义路由:


// 测试队列

Route::get('testQueue','TestsController@testQueue');

在TestsController中定义testQueue方法:


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Models\User;

use App\Jobs\SendMailToUser;

class TestsController extends Controller

{

    public function testQueue(){

        $user = User::find(1);

        dispatch(new SendMailToUser($user));

    }

}

在浏览器中访问 http://larabbs.test/testQueue,很快就收到了邮件:

认识队列

参考:

1. 文档

2. L02 Laravel 教程 - Web 开发实战进阶 ( Laravel 9.x )

3. Laravel 基于redis队列的解析

4. laravel 队列之队列消息与发送邮件

5. Laravel 队列系列 —— 基于 Redis 实现任务队列的基本配置和使用

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 2

补充队列的使用场景:

  1. 在用户预期是需要等待的行为,比如:开发票
  2. 与当前请求业务无关,比如在我发送了这条评论之后,系统需要给你发送一个通知
3年前 评论
Moonshadow2333 (楼主) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!