为啥要学?

还不是因为自己菜,队列之前的接触的也少,正好这2天没啥事,就想好好了解一下队列的基本使用,至少以后别人问起来,我也能大胆的说自己用过啊!

notice:queue安装,自行composer就行,不过要注意版本,因为现在已经出到TP6了

首先我们需要先创建队列,不赘述了,直接上代码

支持的队列方式有很多:db,redis等等,这里使用的redis队列

如果你安装成功在你tp5.1的config文件夹下会有一个queue.php的配置文件,里面去改redis的配置就行

config/queue.php

'connector'  => 'Redis',            // Redis 驱动
    'expire'     => 60,             // 任务的过期时间,默认为60秒; 若要禁用,则设置为 null
    'default'    => 'default',      // 默认的队列名称
    'host'       => '', // redis 主机ip
    'port'       => 6379,           // redis 端口
    'password'   => '',             // redis 密码
    'select'     => 15,             // 使用哪一个 db,默认为 db0
    'timeout'    => 0,              // redis连接的超时时间
    'persistent' => false,          // 是否是长连接

创建队列--数据入队

app\index\controller\JobTest

<?php
/**
 * Created by PhpStorm.
 * User: mayn
 * Date: 2019/10/12
 * Time: 16:47
 */

namespace app\index\controller;

use think\Queue;
class JobTest
{

    public function actionWithHelloJob(){
        // 1.当前任务将由哪个类来负责处理。
        //   当轮到该任务时,系统将生成一个该类的实例,并调用其 fire 方法
        //$jobHandlerClassName  = 'application\index\job\Hello';  //这里千万不要写成这个,不然将会失败
        $jobHandlerClassName  = 'app\index\job\Hello';
        // 2.当前任务归属的队列名称,如果为新队列,会自动创建
        $jobQueueName     = "helloJobQueue";
        // 3.当前任务所需的业务数据 . 不能为 resource 类型,其他类型最终将转化为json形式的字符串
        //   ( jobData 为对象时,需要在先在此处手动序列化,否则只存储其public属性的键值对)
        $jobData          = [ 'ts' => time(), 'bizId' => uniqid() , 'a' => 1 ] ;
        $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.';
        }
    }

}

队列处理--出队

app\index\job\Hello

<?php
/**
 * Created by PhpStorm.
 * User: mayn
 * Date: 2019/10/12
 * Time: 16:53
 */

namespace app\index\job;

use think\Db;
use think\queue\job;
class Hello
{

    /**
     * @param job $job      当前的任务对象
     * @param $data         发布任务时自定义的数据
     */
    public function fire( job $job,$data ){



        $isJobDone = $this->doHelloJob($data);
        if ($isJobDone) {
            //如果任务执行成功, 记得删除任务
            print_r("<info>Hello Job has been done and deleted"."</info>\n");
            $job->delete();
        }else {
            if ($job->attempts() > 3) {
                //通过这个方法可以检查这个任务已经重试了几次了
                print_r("<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秒后再执行
            }
        }
    }

    public function failed($data){//发送失败写入系统日志
        cache('failtime',time());

    }


    /**
     * 有些消息在到达消费者时,可能已经不再需要执行了
     * @param array|mixed    $data     发布任务时自定义的数据
     * @return boolean                 任务执行的结果
     */
    private function checkDatabaseToSeeIfJobNeedToBeDone($data){
        return true;
    }


    /**
     * 根据消息中的数据进行实际的业务处理
     * @param array|mixed    $data     发布任务时自定义的数据
     * @return boolean                 任务执行的结果
     */
    private function doHelloJob($data) {
        // 根据消息中的数据进行实际的业务处理...
        file_put_contents('aaaa.txt',$data,FILE_APPEND);
        /*$info = [
            'user_name' => $data['bizId'],
        ];
        $res = Db::name('user')->insert($info);
        if( $res ){
            return true;
        }else{
            return false;
        }*/

    }

执行:

入队:项目域名/index.php/index/job_test/actionWithHelloJob

数据处理:php think queue:work --queue helloJobQueue (单次执行) ||

​ php think queue:listen --queue helloJobQueue(一直会监听)

02-12 04:26