最近公司遇到客户反馈问题;
说是下单反应慢;
我打开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
的命令,保证自己的队列可以正确执行;
本文为史大坨原创文章,转载无需和我联系,但请注明来自史大坨博客https://www.shidatuos.cn