• thinkphp6 使用redis 实现消息队列


    安装

    composer require topthink/think-queue

    配置

    配置文件位于 config/queue.php

    公共配置

    [
        'default'=>'sync' //驱动类型,可选择 sync(默认):同步执行,database:数据库驱动,redis:Redis驱动//或其他自定义的完整的类名
    ]

    配置消息队列的驱动
    根据选择的存储方式,在appconfigqueue.php这个配置文件中,添加消息队列对应的驱动配置

    创建任务类

    单模块项目推荐使用 appjob 作为任务类的命名空间 多模块项目可用使用 appmodulejob 作为任务类的命名空间 也可以放在任意可以自动加载到的地方

    任务类不需继承任何类,如果这个类只有一个任务,那么就只需要提供一个fire方法就可以了,如果有多个小任务,就写多个方法,下面发布任务的时候会有区别
    每个方法会传入两个参数 thinkqueueJob $job(当前的任务对象) 和 $data(发布任务时自定义的数据)

    还有个可选的任务失败执行的方法 failed 传入的参数为$data(发布任务时自定义的数据)

    例一:消息的消费与删除
    namespace appjob; use thinkqueueJob; class Job1{ public function fire(Job $job, $data){ //....这里执行具体的任务 if ($job->attempts() > 3) { //通过这个方法可以检查这个任务已经重试了几次了 } //如果任务执行成功后 记得删除任务,不然这个任务会重复执行,直到达到最大重试次数后失败后,执行failed方法 $job->delete(); // 也可以重新发布这个任务 $job->release($delay); //$delay为延迟时间 } public function failed($data){ // ...任务达到最大重试次数后,失败了 } }
    例二:
    namespace applibjob; use thinkqueueJob; class Job2{ public function task1(Job $job, $data){ } public function task2(Job $job, $data){ } public function failed($data){ } }
    例三:多模块举例
    <?php
    /**
    * 消息队列(queue)使用方法
    * 使用redis实现消息队列demo
    */

    namespace appcrmjobexport;


    use thinkfacadeDb;
    use thinkqueueJob;

    class QueueJobTest
    {

    public function fire(Job $job,$data){
    // 如有必要,可以根据业务需求和数据库中的最新数据,判断该任务是否仍有必要执行.
    $isJobStillNeedToBeDone = $this->checkJobNeedIfDone($data);
    if(!$isJobStillNeedToBeDone){
    //删除任务
    $job->delete();
    return;
    }
    $isJobDone = $this->saveInfo($data);
    //如果任务执行完成,删除此队列任务,
    if($isJobDone){
    //删除任务
    $job->delete();
    }else{
    //通过这个方法可以检查这个任务已经重试了几次了
    if ($job->attempts() > 3) {
    //如果大于设置的次数3,可执行删除任务或重新发布此任务
    //此处直接执行删除任务
    $job->delete();
    //--begin-重新发布此任务-------
    //$job->release(2); //参数为设置的延迟时间,表示该任务延迟2秒后再执行
    //--end-重新发布此任务--------——
    }
    }
    }

    /**
    * 可选的任务失败执行的方法,此处只作列举
    * 任务失败,执行failed方法
    * @param $data 发布任务时自定义的数据
    */
    //public function failed($data){
    //// ...任务达到最大重试次数后,失败了
    //执行失败的业务代码
    //}

    /**
    * 有些消息在到达消费者时,可能已经不再需要执行了
    * @param array|mixed $data 发布任务时自定义的数据
    * @return boolean 任务执行的结果
    */
    private function checkJobNeedIfDone($data){
    //可查询数据库确认是否需要继续执行,比如订单支付的状态更改等后续操作
    //此处省略业务逻辑,直接返回true,表示继续执行
    return true;
    }

    /**
    * 任务执行的业务代码
    * 如发送邮件,数据入库等
    */
    private function saveInfo($data){
    //此处模拟数据入库
    $res = Db::name('test')->insert(
    [
    'title' => $data['title'],
    'content' => $data['content'],
    'add_time' => time()
    ]
    );
    if($res){
    return true;
    }else{
    return false;
    }
    }
    }

    发布任务

    两个方法

    thinkfacadeQueue::push($job, $data = '', $queue = null);       //立即执行

    或 

    thinkfacadeQueue::later($delay, $job, $data = '', $queue = null);  //延时执行,在参数 $delay 秒后执行在$delay秒后执行

    $job 是任务名
    单模块的,且命名空间是appjob的,比如上面的例子一,写Job1类名即可
    多模块的,且命名空间是appmodulejob的,写model/Job1即可
    其他的需要些完整的类名,比如上面的例子二,需要写完整的类名applibjobJob2
    如果一个任务类里有多个小任务的话,如上面的例子二,需要用@+方法名applibjobJob2@task1applibjobJob2@task2

    $data 是你要传到任务里的参数

    $queue 队列名,指定这个任务是在哪个队列上执行,同下面监控队列的时候指定的队列名,可不填

    例:

    文件路径:

    任务名(类名):appcrmjobexportQueueJobTest

    传到任务里的参数:['title' => '队列任务入库demo','content' => 'xxxx内容']

    队列名(可不填):queueJobTest

    //生产者业务代码中把任务push到队列中:

    thinkfacadeQueue::push('appcrmjobexportQueueJobTest',  ['title' => '队列任务入库demo','content' => 'xxxx内容'], 'queueJobTest')

    发布任务

     浏览器中访问:http://localhost/index.php/Test/actionQueueJobTest  

    监听任务并执行

    消费者进行处理队列

    &> php think queue:listen
    
    &> php think queue:work

    两种,具体的可选参数可以输入命令加 --help 查看

    处理任务

    方式一:

    切换当前终端窗口的目录到项目根目录下,执行

    php think queue:work --queue queueJobTest

    php think queue:listen --queue queueJobTest

    方式二:

    supervisor安装参考:https://www.cnblogs.com/chihuobao/p/15341719.html  

    可配合supervisor使用,保证进程常驻

    添加queueJobTest.ini文件输入如下内容


    [program:queueJobTest]
    user=root
    command = php /home/wwwroot/test_crm/think queue:listen --queue queueJobTest --timeout 0 --memory 1024
    autostart=true
    autorestart=false
    stderr_logfile=/tmp/queue_stderr.log
    stdout_logfile=/tmp/queue_stdout.log

  • 相关阅读:
    extjs使用笔记-21
    如何安装整个linux系统中所需要的mp3播放库插件? 可以在安装rpmfusion仓库后直接通过dnf install进行按照就可以了
    aria2的下载配置
    再谈fedora23下Virutalbox的安装. --问题的关键在于 安装kernel-devel包
    extjs的使用笔记2
    提高迅雷的下载速度
    extjs的使用笔记
    expr的字符串操作 表达式: length, index, match, substr等
    弄懂linux shell对包含$的变量的执行过程?
    从0开始安装fedora23的笔记-- 以及使用fedora的常规问题-3
  • 原文地址:https://www.cnblogs.com/chihuobao/p/15344236.html
Copyright © 2020-2023  润新知