什么是队列?
对数据的"存"和"取"有严格要求的线性存储结构
队列的两端都"开口",要求数据只能从一端进,从另一端出。
进数据的一端为 "队尾",出数据的一端为 "队头",数据元素进队列的过程称为 "入队",出队列的过程称为 "出队"。
队列的特性?
1.数据从队列的一端进,另一端出;
2.数据的入队和出队遵循"先进先出"的原则。
遵循 "先进先出" 的原则,即最先进队列的数据元素,同样要最先出队列。拿图 中的队列来说,从数据在队列中的存储状态可以分析出,元素 1 最先进队,其次是元素 2,最后是元素 3。此时如果将元素 3 出队,根据队列 "先进先出" 的特点,元素 1 要先出队列,元素 2 再出队列,最后才轮到元素 3 出队列
队列的使用目的
1.队列的目的是将耗时的任务延时处理,提升效率,大幅度缩短Web请求和响应的时间。
2.解耦,即降低生产者和消费者之间的依赖关系。
3.支持并发,即生产者和消费者可以是两个独立的并发主体,互不干扰的运行。
队列分为:生产者和消费者
1.把数据放到消息队列叫做 生产者。
2.从消息队列里边取数据叫做 消费者。
1.创建任务类
php artisan make:Jobs SendEmails
<?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 App\Http\Controllers\EmailController;
class SendEmails implements ShouldQueue
{
//生成的类实现了 Illuminate\Contracts\Queue\ShouldQueue 接口,这意味着这个任务将会被推送到队列中,而不是同步执行。
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* 任务最大尝试次数。
*
* @var int
*/
public $tries = 3;
/**
* 任务运行的超时时间。
*
* @var int
*/
public $timeout = 120;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$email = new EmailController();
if(!$email->sendEmail()){
// 发送邮件,通知管理员
event($email->sendEmail());
}
}
}
1.如果想要让任务推送到特定的连接中,例如 redis 或者 sqs,那么需要设置 conneciton 变量。
2.如果想要让任务推送到特定的队列中去,可以设置 queue 变量。
3.如果想要让任务延迟推送,那么需要设置 delay 变量。
4.如果想要设置任务至多重试的次数,可以使用 tries 变量;
5.如果想要设置任务可以运行的最大秒数,那么可以使用 timeout 参数。
6.设置延迟执行一个队列中的任务。
7.队列也可指定优先级。
2.生产队列
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Model\User;
use App\Jobs\SendEmails;
class LoginController extends Controller
{
public function login() {
dispatch( new SendEmails());
}
3.运行队列
//执行一条队列任务
php artisan queue:work --once
//一次运行全部队列
php artisan queue:work
4.laravel 队列服务的任务调度
laravel 的队列服务由两个进程控制,一个是生产者,一个是消费者。这两个进程操纵了 redis 三个队列,其中一个 List,负责即时任务,两个 Zset,负责延时任务与待处理任务。
生产者负责向 redis 推送任务,如果是即时任务,默认就会向 queue:default 推送;如果是延时任务,就会向 queue:default:delayed 推送。
消费者轮询两个队列,不断的从队列中取出任务,先把任务放入 queue:default:reserved 中,再执行相关任务。如果任务执行成功,就会删除 queue:default:reserved 中的任务,否则会被重新放入 queue:default:delayed 队列中。
5.队列失败处理
# 创建队列作业的表
php artisan queue:failed-table
# 迁移数据
php artisan migrate
ID 任务的 ID (任务 ID 可以被用在重试失败的任务上)
Connection 连接
Queue 队列
Failed At 失败时间
image.png
php artisan queue:retry ID 所有用all代替
queue:failed 列出所有失败的队列
queue:failed-table 创建失败队列数据表迁移
queue:flush 清除所有失败的队列作业
queue:forget 删除失败的队列作业
queue:listen 监听队列
queue:restart 重新启动队列工作进程
queue:retry 重试失败的队列
queue:table 创建队列数据库表迁移
queue:work 作为守护程序开始处理队列上的作业
6.队列监控面板
Horizon 为 Laravel 官方发布的队列监控面板,他可以更加直观的展示队列的运行状况。
composer require laravel/horizon
发布配置文件:
php artisan vendor:publish --provider="Laravel\Horizon\HorizonServiceProvider"
//执行完成会在 config 目录创建 horizon.php 文件作为配置文件。
启动服务
php artisan horizon
配置路由,访问即可!