队列可用来执行发送邮件、短信、推送等,还可用来做高并发时将库存放入队列中,来防止超卖的情况,还可用来创建订单时将订单加入延时队列中用来自动更改订单为过期状态。
使用队列可以异步执行消耗时间的任务,降低请求的响应时间
队列文件的位置:
app/Jobs
创建队列(如创建一个发送邮件的队列文件):
php artisan make:job SendEmail
注意:队列文件更改后要重启队列才能生效
队列重启:
php artisan queue:restart
监听队列(只有监听状态队列才能正常运行):
php artisan queue:listen //监听队列请求,只要运行着,就能一直接受请求,除非手动终止
php artisan queue:work //默认只执行一次队列请求,当请求执行完成后就终止
php artisan queue:work --daemon //同 listen 一样,只要运行着,就能一直接受请求,不一样的地方是在这个运行模式下,当新的请求到来的时候,不重新加载整个框架 , 而是直接 fire 动作.能看出来,queue:work --daemon 是最高级的,一般推荐使用这个来处理队列监听
队列监听守护进程请参考:链接
使用队列:
控制器直接使用:
$data['id'] = $id;
$job = new SendEmail($data);
$job->dispatch($data);
为了使队列的使用逻辑更加清晰及方便项目复用,可在 app/Http/Controllers 目录创建 Jobs 文件夹用来起到过度作用,再创建 SendEmailController.php 文件,文件内容如下:
<?php
namespace App\Http\Controllers\Jobs;
use App\Http\Controllers\BaseController;
use App\Jobs\SendEmail;
class SendEmailController extends BaseController
{
//可以给队列起个名字
public $name = 'send_email';
//加入队列
public static function runJob($data)
{
$job = new SendEmail((new self())->name,$data);
(new self())->dispatch($job);
}
}
然后在控制器中使用:
$job = new SendEmailController();
$job::runJob($data);
注:若提示自定义类无法找到,可能是不符合 psr-4自动加载规范, 需在 composer.json 文件中找到 autoload,加入我们自定义的Jobs目录:
"autoload": {
"psr-4": {
"App\\": "app/",
"Jobs\\": "app/Http/Jobs"
},
"classmap": [
"database/seeds",
"database/factories",
"app/Http/Jobs"
]
},
在队列文件 app/Jobs/SendEmail.php 中:
<?php
namespace App\Jobs;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SendEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $name;
protected $data;
public function __construct($name,$data)
{
$this->name= $name;
$this->data= $data;
}
/**
* 队列执行的具体内容
*/
public function handle()
{
##执行发送邮件的逻辑
}
}