- 队列在处理耗时并且出错的任务非常有必要,这里我们就来简单实现一下
首先配置使用
redis
为队列库,在
.env
中
QUEUE_DRIVER=redis
创建队列job
php artisan make:job Postjob
控制器中分发队列:
<?php
namespace App\Http\Controllers;
use App\Jobs\Postjob;
use App\Test;
use Illuminate\Http\Request;
use App\Jobs\SendPostEmail;
use App\Post;
class PostController extends Controller
{
public function index()
{
return view('index');
}
public function store(Request $request)
{
for ($i = 0;$i<100;$i++){
$p =['title'=>$request->title,'body'=>$request->body];
$post = Post::create($p);
$this->dispatch(new Postjob($post));//分发队列
}
return redirect()->back()->with('status', 'Your post has been submitted successfully');
}
}
队列处理:
<?php
namespace App\Jobs;
use App\Post;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class Postjob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $post;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(Post $post)
{
//
$this->post = $post;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$ty = $this->post;
$data = ['title'=>$this->post->title,'body'=>$this->post->body];
Test::create($data);
}
}
开启队列任务:
PHP artisan queue:work
队列每次执行都会出现下面的进程
[2019-10-16 15:15:02] Processing: App\Jobs\Postjob
[2019-10-16 15:15:02] Processed: App\Jobs\Postjob
我们进行循环插入数据库数据来模拟长时间的运行,当有插入时就把操作丢到队列中去处理,不用再进行等待,请求一次即可关闭,执行队列
handle()
方法中写入执行操作。
- 上面的例子是创建数据库,获取创建的数据进行操作,在实际情况下,可能是其他类型的操作,没有写入数据库,在队列里面才进行的数据库操作
- 这里就进行简单模拟一下
写个数据接收类用于注入队列控制器
<?php
namespace App\Http;
class TestJob
{
public $name;
public $cont;
/**
* @return mixed
*/
public function getCont()
{
return $this->cont;
}
/**
* @param mixed $cont
*/
public function setCont($cont): void
{
$this->cont = $cont;
}
/**
* @return mixed
*/
public function getName()
{
return $this->name;
}
/**
* @param mixed $name
*/
public function setName($name): void
{
$this->name = $name;
}
}
队列文件进行插入数据库
<?php
namespace App\Jobs;
use App\Http\TestJob;
use App\Test;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class Postjob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $testjob;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(TestJob $testjob)
{
$this->testjob = $testjob;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$data = ['name'=>$this->testjob->getName(),'cont'=>$this->testjob->getCont()];
Test::create($data);
}
}
- 控制器中进行队列分发,直接进行插入数据耗时需要
,推入队列耗时13.58s
,基本脚本运行时间少了一半,让插入数据库放入到了队列进行运行6.52s
public function tt(){
ini_set("memory_limit", "2048M");
set_time_limit(0);
$m1 = memory_get_usage();
$unit = ['b', 'kb', 'mb', 'gb', 'tb', 'pb'];
$t1 = microtime(true);
for ($i = 0;$i<10000;$i++){
$post = new TestJob();
$post->setName($i);
$post->setCont($i);
// $this->dispatch(new Postjob($post));//推入队列
Test::create(['name'=>$i,'cont'=>$i]);
}
$t2 = microtime(true);
$t = number_format($t2-$t1,2).'s';
$m2 = memory_get_usage();
$size = $m2-$m1;
$size = round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $unit[$i];
return $t;
}