thinkphp Queue消息队列

Queue消息队列:

Thinkphp官方团队开发的一个专门支持队列服务的扩展包,使用composer管理,使用起来非常方便

Queue消息队列优点:

  1. Queue内置了 Redis,Database,Topthink ,Sync这四种驱动,本文使用Redis驱动。

  2. Queue消息队列适用于大并发或者返回结果 时间有点长并需要批量操作的第三方接口,可用于短信发送、邮件发送、APP推送。

  3. Queue消息消息可进行发布,获取,执行,删除,重发,失败处理,延迟执行,超时控制等操作。

Queue消息队列缺点:

  1. 一旦需处理数据加入到任务内就不能删除

官方文档地址:

https://packagist.org/packages/topthink/think-queue

安装与配置:

  1. 是用Composer进行安装,命令:composer require topthink/think-queue 2.0.x-dev (这里由于3.0版本需要tp6支持 本文使用tp5.1 故安装2.0.x-dev版)

  2. 配置文件位于 application/config/queue.php

  3. 本文使用类型是Redis,假如你的当前环境没有Redis,则自行安装

  4. 配置文件如下:

    <?php
     return [
         'connector'  => 'Redis',               // 可选驱动类型:sync(默认)、Redis、database、topthink等其他自定义类型
         'expire'     => 60,                    // 任务的过期时间,默认为60秒; 若要禁用,则设置为 null
         'default'    => 'default',             // 默认的队列名称
         'host'       => '127.0.0.1',           // redis 主机ip
         'port'       => 6379,                  // redis 端口
         'password'   => '',                    // redis 连接密码
         'select'     => 0,                     // 使用哪一个 db,默认为 db0
         'timeout'    => 0,                     // redis连接的超时时间
         'persistent' => false,                 // 是否是长连接
     ];
    
  5. 控制器 application\test\controller\Index.php

    <?php
    
    namespace app\test\controller;
    
    use think\Controller;
    use think\facade\Cache;
    use think\Queue;
    
    class Index extends Controller
    {
        public function index()
        {
        }
    
        /**
        * 一个使用了队列的 action
        */
        public function actionWithHelloJob()
        {
    
            // 1.当前任务将由哪个类来负责处理。 
            //   当轮到该任务时,系统将生成一个该类的实例,并调用其 fire 方法
            $jobHandlerClassName  = 'app\test\controller\Hello';
    
            // 2.当前任务归属的队列名称,如果为新队列,会自动创建
            $jobQueueName = "helloJobQueue";
    
            // 3.当前任务所需的业务数据 . 不能为 resource 类型,其他类型最终将转化为json形式的字符串
            //   ( jobData 为对象时,存储其public属性的键值对 )
            $jobData = [
                'name' => 'supperl',
                'age' => 22
            ];
    
            // 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.';
            }
        }
    }
    
  6. 控制器 application\test\controller\Hello.php

    <?php
    
    namespace app\test\controller;
    
    use think\Controller;
    use think\queue\Job;
    
    
    class Hello extends Controller
    {
        /**
        * fire方法是消息队列默认调用的方法
        * @param Job            $job      当前的任务对象
        * @param array|mixed    $data     发布任务时自定义的数据
        */
        public function fire(Job $job, $data)
        {
            // 有些消息在到达消费者时,可能已经不再需要执行了
            $isJobStillNeedToBeDone = $this->checkDatabaseToSeeIfJobNeedToBeDone($data);
            if (!$isJobStillNeedToBeDone) {
                $job->delete();
                return;
            }
    
            $isJobDone = $this->doHelloJob($data);
    
            if ($isJobDone) {
                // 如果任务执行成功, 记得删除任务
                $job->delete();
                print("<info>Hello Job has been done and deleted" . "</info>\n");
            } else {
                if ($job->attempts() > 3) {
                    //通过这个方法可以检查这个任务已经重试了几次了
                    print("<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秒后再执行
                }
            }
        }
    
        /**
        * 有些消息在到达消费者时,可能已经不再需要执行了
        * @param array|mixed    $data     发布任务时自定义的数据
        * @return boolean                 任务执行的结果
        */
        private function checkDatabaseToSeeIfJobNeedToBeDone($data)
        {
            return true;
        }
    
        /**
        * 根据消息中的数据进行实际的业务处理...
        */
        private function doHelloJob($data)
        {
            print("<info>Hello Job Started. job Data is: " . var_export($data, true) . "</info> \n");
            print("<info>Hello Job is Fired at " . date('Y-m-d H:i:s') . "</info> \n");
            print("<info>Hello Job is Done!" . "</info> \n");
            return true;
        }
    }
    
  7. 执行创建生成者推送至消费者 php index.php test/index/actionWithHelloJob

    1. 显示 2020-03-26 16:13:48 a new Hello Job is Pushed to the MQ<br>
  8. 消费者消费 php think queue:work --queue helloJobQueue

    1. 显示
      <info>Hello Job Started. job Data is: array (
      'name' => 'supperl',
      'age' => 22,
      )</info> 
      <info>Hello Job is Fired at 2020-03-26 16:21:34</info> 
      <info>Hello Job is Done!</info> 
      <info>Hello Job has been done and deleted</info>
      
  9. 配置supervisord 进程守护,待续~~~

发布了4 篇原创文章 · 获赞 0 · 访问量 66

猜你喜欢

转载自blog.csdn.net/qq_32450143/article/details/105122665