Laravel 队列系统实现(一) 创建任务篇

最近公司遇到客户反馈问题;
说是下单反应慢;
我打开f12;
我看了一下接口的请求时间 平均下来10秒以上 (心里想想确实比较慢啊);
(╥╯^╰╥)
开始排查问题;
刚开始我以为是sql查询效率的问题;
开始优化sql;
没有加索引的地方加索引;
后面发现请求的时间还是没有提升上去;
心里一想,下单这一块处理的逻辑确实有点多啊;
计算商品价格 (商品规格 , 商品运费 , 营销组件 , 减去商品库存 , 通知商家的模板消息 , 通知客户的模版消息 ....);
php是单线程的;
一个接口里面处理这么多的逻辑,不慢才怪;
后面想到了用laravel的队列来处理;
用队列的话主要是因为可以用过用异步去处理;
这里简单举接地气一个例子,什么是同步 , 什么是异步;
假如我们需要做3件事 煮饭 需要5分钟, 洗衣 5分钟 ,晒衣服 2分钟;
一看我就是居家的好男人;
方便大家理解看图;
异步图解
好 废话不多说,上文档 [[ Laravel 5.5 文档 ] 进阶系列 —— Laravel 队列系统实现及使用教程](https://laravelacademy.org/post/8369.html "[ Laravel 5.5 文档 ] 进阶系列 —— Laravel 队列系统实现及使用教程");
但说实话;
我一上来看文档我是比较懵逼的;
看不懂;
原谅我是一个小白;
没事 , 不明白的可以跟着我往下看;
首先是队列驱动的设置;
我们这里使用的是数据库驱动;
配置 .env文件

QUEUE_DRIVER=database

或者直接进入到项目的configqueue.php 配置改成如下:

'default' => 'database',

进入到项目 artisan 的命令行;

php artisan queue:table //创建默认的任务表文件
php artisan migrate //生成 jobs 表

之后你会发现 databasemigrations 多出了一个文件;
这是 laravel 默认的任务表;
看看你的项目数据库是不是多出了一张表;
存在 jobs 表说明执行成功了;
耶!!;
接下来是生成任务类

php artisan make:job TestJob //创建任务类

在 AppJobsTestJob.php 的代码如下:

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Log;

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

    public $a;

    /**
     * 任务最大尝试次数。
     *
     * @var int
     */
    public $tries = 3;

    /**
     * 任务运行的超时时间。
     *
     * @var int
     */
    public $timeout = 120;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($pa)
    {
        $this->a = $pa;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        Log::info('TestJob poset title is ' . json_encode($this->a));
    }
}

定义路由

Route::get('/',Api\ApiController::class."@index");

具体的 ApiController 下的 index方法

//上面需要 use App\Jobs\TestJob;

public function index(){
        $res = DB::table("app")->where('id','<',66)->get();
        foreach ($res as $item){
            $this->dispatch(new TestJob($item));
        }
        return 'yes';
}

本地访问一下;
访问本地根目录
上面的打印是我在底层打印laravel任务 的任务类是怎么入库的;
主要看输出了yes 就代表成功了;
然后我们可以看到jobs表已经成功添加了3条数据;
开心;
接下来我们就可以运行队列进程了;

php artisan queue:work

使用 queue:work 命令运行这个队列进程。请注意,队列进程开始运行后,会持续监听队列,直至你手动停止或关闭终端()

vagrant@homestead:/vagrant/api$ php artisan queue:work
[2019-07-28 15:04:38] Processing: App\Jobs\TestJob
[2019-07-28 15:04:38] Processed:  App\Jobs\TestJob
[2019-07-28 15:04:38] Processing: App\Jobs\TestJob
[2019-07-28 15:04:38] Processed:  App\Jobs\TestJob
[2019-07-28 15:04:38] Processing: App\Jobs\TestJob
[2019-07-28 15:04:38] Processed:  App\Jobs\TestJob

出现类似上面的说明执行成功了;
这个时候我们再看看laravel默认的日志文件出现了以下日志;

[2019-07-28 15:04:38] local.INFO: TestJob poset title is {"id":1,"name":"\u524d\u53f0\u7f51\u7ad9"}  
[2019-07-28 15:04:38] local.INFO: TestJob poset title is {"id":48,"name":"\u6559\u80b2\u4ea7\u54c1\u5e93"}  
[2019-07-28 15:04:38] local.INFO: TestJob poset title is {"id":65,"name":"\u56fe\u4e66\u4f01\u4e1a\u7248"}

出现了这三条日志文件;
日志文件里面出现的就是我们在工作类上面写的业务逻辑;
刚才也说到 使用 queue:work 命令运行这个队列进程;
但是在我们真实的开发过程中;
不可能一直开着这个命令行这个窗口;
对吧;
为了保持队列进程 queue:work 持续在后台运行,需要使用进程守护程序,比如 Supervisor 来确保队列进程持续运行;
还有一点大家也需要注意;
重要的事情说三遍;
(只要是修改了任务类里面的逻辑代码都需要重启队列服务) * 3;

php artisan queue:restart //重启队列服务

拓展:Supervisor 则是用来监听队列的任务,并在队列存在任务的情况下自动帮我们去执行,免去手动敲 php artisan queue:work 的命令,保证自己的队列可以正确执行;

在加班!!都嫁出胡子了

史大坨博客
请先登录后发表评论
  • 最新评论
  • 总共0条评论