- 隊列在處理耗時并且出錯的任務非常有必要,這裡我們就來簡單實作一下
首先配置使用
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;
}