一、安装tp6-queue
composer require topthink/think-queue
二、创建消息队列
1.安装完成后会在config文件夹下生产queue.php配置文件
2.建议修改default为redis
3.创建队列和通知
1)新增 \app\job\JobTest.php 控制器,在该控制器中添加 fire 方法(注意目录名称job必须是小写)
2)fire方法是消息队列默认调用的方法
namespace app\job;
use think\facade\Db;
use think\Log;
use think\queue\Job;
class JobTest
{
/**
* fire方法是消息队列默认调用的方法
*
* @param Job $job
* 当前的任务对象
* @param array|mixed $data
* 发布任务时自定义的数据
*/
public function fire(Job $job, $data)
{
while (true) {
// 有些消息在到达消费者时,可能已经不再需要执行了
$isJobStillNeedToBeDone = $this->checkDatabaseToSeeIfJobNeedToBeDone($data);
if (!$isJobStillNeedToBeDone) {
$job->delete();
return;
}
$isJobDone = $this->doJob($data);
echo $isJobDone;
if ($isJobDone) {
// 如果任务执行成功, 记得删除任务
$job->delete();
print(date('Y-m-d H:i:s') . "<info>Hello Job has been done and deleted" . "</info>\n");
} else {
if ($job->attempts() > 3) {
// 通过这个方法可以检查这个任务已经重试了几次了
print(date('Y-m-d H:i:s') . "<warn>Hello Job has been retried more than 3 times!" . "</warn>\n");
$job->delete();
// 也可以重新发布这个任务
// print("<info>Hello Job will be availabe again after 2s."."</info>\n");
// $job->release(2); //$delay为延迟时间,表示该任务延迟2秒后再执行
}
}
sleep(1);
}
}
/**
* 有些消息在到达消费者时,可能已经不再需要执行了
*
* @param array|mixed $data
* 发布任务时自定义的数据
* @return boolean 任务执行的结果
*/
private function checkDatabaseToSeeIfJobNeedToBeDone($data)
{
return true;
}
/**
* 根据消息中的数据进行实际的业务处理...
*/
private function doJob($data)
{
//
}
}
4.在项目中创建调用队列的接口
<?php
namespace app\controller;
use think\facade\Queue;
class JobCtrl
{
/**
* 一个使用了队列的 action
*/
public function actionJobTest()
{
// 1.当前任务将由哪个类来负责处理。
// 当轮到该任务时,系统将生成一个该类的实例,并调用其 fire 方法
$jobHandlerClassName = 'app\job\JobTest@fire';
// 2.当前任务归属的队列名称,如果为新队列,会自动创建
$jobQueueName = "AutoJob";
// 3.当前任务所需的业务数据 . 不能为 resource 类型,其他类型最终将转化为json形式的字符串
// ( jobData 为对象时,需要在先在此处手动序列化,否则只存储其public属性的键值对)
$jobData = [
'ts' => time(),
'bizId' => uniqid(),
'a' => 1
];
// 4.将该任务推送到消息队列,等待对应的消费者去执行
$isPushed = Queue::push($jobHandlerClassName, $jobData, $jobQueueName);
// database 驱动时,返回值为 1|false ; redis 驱动时,返回值为 随机字符串|false
if ($isPushed !== false) {
echo date('Y-m-d H:i:s') . " a new Hello Job is Pushed to the MQ" . "<br>";
} else {
echo 'Oops, something went wrong.';
}
}
}
三、执行消息队列
1.先调用队列接口:
例如:https://test/actionJobTest
2.在框架目录下开启队列
php think queue:work --queue AutoJob
AutoJob为设置的队列名称
四、守护进程(Supervisor)
宝塔安装:
1)在软件商店搜索Supervisor管理器
2)添加守护进程,按要求添加即可
五、异常错误
1.若使用composer 安装queue报错:
1)使用composer self-update 命令更新composer
2)删除composer.lock文件,使用composer clearcache命令,再使用composer update,然后再操作安装queue命令
2.消息队列执行一分钟后自动停止,将超时时间设置为0
1)php think queue:work --queue AutoJob --timeout=0