Bootstrap

TP6 topthink/think-queue

安装 topthink/think-queue

composer require topthink/think-queue

修改配置文件

安装成功后自动生成 config/queue.php

<?php
return [
    'default'     => 'redis',
    'connections' => [
        'sync'     => [
            'type' => 'sync',
        ],
        'database' => [
            'type'       => 'database',
            'queue'      => 'default',
            'table'      => 'jobs',
            'connection' => null,
        ],
        'redis'    => [
            'type'       => 'redis',
            'queue'      => 'default',
            'host'       => '127.0.0.1',
            'port'       => 6379,
            'password'   => '',
            'select'     => 0,
            'timeout'    => 0,
            'persistent' => false,
        ],
    ],
    'failed'      => [
        'type'  => 'none',
        'table' => 'failed_jobs',
    ],
];

创建文件

image.png

job目录下是队列的执行文件
listen目录是队列的注册文件

listen 目录 HelloListen.php 文件内容

<?php

namespace app\Listen;


use think\facade\Queue;

class HelloListen {
    //任务执行类(消费者消费的处理逻辑)
    public static $jobHandlerClassName = "app\job\Hello@fire";
             
    //队列名,如不存在会自动创建
    public static $jobQueueName = "helloJobQueue";

    public static function index($jobData){

        //延迟推送,推送后等待消费者消费
        //$isPushed = Queue::later(15, self::$jobHandlerClassName , $jobData , self::$jobQueueName );

        //立即推送,等待消费者消费
        $isPushed = Queue::push(self::$jobHandlerClassName , $jobData , self::$jobQueueName );

        // database 驱动时,返回值为 1|false  ;   redis 驱动时,返回值为 随机字符串|false
        if( $isPushed !== false ){
            echo '队列添加成功';
            return true;
        }else{
            echo '队列添加失败';
            return false;
        }
    }         
}

job目录 Hello.php内容

<?php

namespace app\job;

use think\queue\Job;

class Hello
{
    public $queue = 'Hello';

    /**
     * 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();
        } else {
            if ($job->attempts() > 3) {
                //通过这个方法可以检查这个任务已经重试了几次了
                $job->delete();
                // 也可以重新发布这个任务
                //$job->release(2); //$delay为延迟时间,表示该任务延迟2秒后再执行
            }
        }
    }


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

    /**
     * 根据消息中的数据进行实际的业务处理
     * @param array|mixed $data 发布任务时自定义的数据
     * @return boolean                 任务执行的结果
     */
    private function doHelloJob($data)
    {
        // 根据消息中的数据进行实际的业务处理...
        // test
        echo "<hr>";
        echo '正在工作中....' . date('Y-m-d H:i:s');
        return true;
    }
}

使用

监控任务 终端下执行命令

php think queue:listen --queue helloJobQueue

向队列 helloJobQueue 填充数据

HelloListen::index($data);

其他命令

php think queue:listen --help

php think queue:listen
–queue helloJobQueue \ //监听的队列的名称
–delay 0 \ //如果本次任务执行抛出异常且任务未被删除时,设置其下次执行前延迟多少秒,默认为0
–memory 128 \ //该进程允许使用的内存上限,以 M 为单位
–sleep 3 \ //如果队列中无任务,则多长时间后重新检查
–tries 0 \ //如果任务已经超过重发次数上限,则进入失败处理逻辑,默认为0
–timeout 60 // work 进程允许执行的最长时间,以秒为单位



作者:双月鸟
链接:https://www.jianshu.com/p/7cc1626e240d
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

;