Laravel队列为不同的后台队列服务提供统一的 API,例如 Beanstalk,Amazon SQS,Redis,甚至其他基于关系型数据库的队列。队列的目的是将耗时的任务延时处理,使用于图片生成、视频转换、日志储存等比如发送邮件,从而大幅度缩短 Web 请求和响应的时间。
默认情况下,我们可以在Laravel 生成的 .env 文件进行配置
//QUEUE_DRIVER=sync 把队列的驱动设置修改为redis
QUEUE_DRIVER=redis
//加上下列配置
QUEUE_CONNECTION=redis
REDIS_CLIENT=predis
Redis: predis/predis ~1.
composer require predis/predis
我们在确定依赖以及配置是正确后我们可以使用命令来进行队列的任务类创建
php artisan make:job xxxxxxx
队列的任务类都默认放在 app/Jobs 目录下。如果这个目录不存在,那当你运行 make:job Artisan 命令时目录就会被自动创建
写好任务类后,就能通过 dispatch 辅助函数来分发它了。唯一需要传递给 dispatch 的参数是这个任务类的实例
我们直接生成一个订单 然后把这个订单的参数传给我们的任务去
$order = Order::create([
'out_trade_no' => random_int(0, 999999),
'total_price' => $total_price,
'state ' => 0,
'closed' => 0
])
//我们把需要执行的任务实例写上去任务实例里面传值你自己可以进行任意值传输
//因为我们例子为关闭订单 那我就把订单的参数以及关闭订单的时间传过去
$this->dispatch(new CloseOrder($order, 6000));
任务类的结构很简单 一般来说可以直接让队列用来调用此任务的 handle 方法
因为我们需要在订单下单后的某个时间来进行判断支付并执行关闭未支付订单 那么我们就不可以直接调用handle 方法 我们需要借助延迟分发来实现
可以用任务实例的 delay 方法
例如,我们之前传的参数指定任务在分配后 10 分钟后进行处理
namespace App\Jobs;
use App\Admin\Models\Orders;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class CloseOrder implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $order;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(Orders $order, $delay)
{
//在创建订单后传来的order参数
$this->order = $order;
// 设置延迟的时间,delay() 方法的参数代表多少秒之后执行
$this->delay($delay);
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//判断订单状态是否为已支付的订单
if ($this->order->state !=0) {
return;
}
// 通过事务执行 sql
\DB::transaction(function () {
// 将订单关闭
$this->order->update(['closed' => 1]);
});
}
}
在我们写好了任务类后我们需要运行处理器
队列处理器,当新任务被推到队列中时它能处理这些任务。你可以通过 queue:work 命令来运行处理器。要注意,一旦 queue:work 命令开始,它将一直运行,直到你手动停止或者你关闭控制台:
php artisan queue:work
要让 queue:work 进程永久在后台运行,你应该使用进程监控工具,比如 ==Supervisor ==来保证队列处理器没有停止运行。
一定要记得,队列处理器是长时间运行的进程,并在内存里保存着已经启动的应用状态。这样的结果就是,处理器运行后如果你修改代码那这些改变是不会应用到处理器中的。所以在你重新部署过程中,一定要 重启队列处理器 。