TP消息队列执行

安装queue

composer 安装 think-queue

composer require topthink/think-queue

  

配置文件

在 \application\extra 新建queue.php 为 queue 的配置文件
声明启动redis (服务器redis需要先开启安装redis扩展)

return [
    'connector'  => 'Redis',          // Redis 驱动
    'expire'     => null,             // 任务的过期时间,默认为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,            // 是否是长连接
];
————————————————

  

queue服务基类

首先要写一个声明一个服务基类 命名空间及文件夹名 自己定义好 到直接位置
我这里是在 \application\common\library\task\OrderClose.php 这个路径

namespace app\common\library\task;

use app\common\controller\Frontend;
use think\Lang;
use think\Response;
use think\queue\Job;

/**
 * 未支付订单到期自动关闭任务
 */
class OrderClose
{
    
    /**
     * fire方法是消息队列默认调用的方法
     * @param Job            $job      当前的任务对象
     * @param array|mixed    $data     发布任务时自定义的数据
     */
    public function fire(Job $job, $data)
    {
        // 此处做一些 check,提前判断是否需要执行
        // $isJobStillNeedToBeDone = $this->checkJob($data);
        // if(! $isJobStillNeedToBeDone){
        //     $job->delete();
        //     return;
        // }
        // if ($job->attempts() > 6) {
        //     $job->delete();
        //     // 也可以重新发布这个任务
        //     //$job->release(2); // $delay为延迟时间,表示该任务延迟2秒后再执行
        // }
        // 执行逻辑处理(即:你需要该消息队列做什么)
        $isJobDone = $this->doJob($data);
        if ($isJobDone) {
            // 如果任务执行成功,记得删除任务
            $job->delete();
            // $job->release(10);
        } else {
            //删除任务
            $job->delete();
            // 通过这个方法可以检查这个任务已经重试了几次了
            
        }
    }
    
    /**
     * 有些消息在到达消费者时,可能已经不再需要执行了
     * @param $data 发布任务时自定义的数据
     * @return bool 任务执行的结果
     */
    private function checkJob($data){
        // $order_id = !empty($data['order_id']) ? $data['order_id'] : '';
        // if(!$order_id) return false;
        // $orderModel = new \app\api\model\order\Order;
        // $orderInfo = $orderModel->where(['id'=>$order_id])->find();
        // if(!$orderInfo) return false;
        // if($orderInfo->status != '1') return false;
        // //更新订单数据
        // $updateData = [
        //     'status'=>'10',
        //     'close_time'=>time(),
        //     'remarks'=>'未支付订单超时自动关闭'
        // ];
        // $ret = $orderModel->save($updateData);
        // if($ret){
        //     return true;
        // }else{
        //     return false;    
        // }
    }
    
    /**
     * 根据消息中的数据进行实际的业务处理...
     * @param $data
     * @return bool
     */
    private function doJob($data)
    {
        $order_id = !empty($data['order_id']) ? $data['order_id'] : '';
        if(!$order_id) return false;
        $orderInfo = \app\api\model\order\Order::where(['id'=>$order_id])->find();
        // \think\Log::write(['msg'=>'测试队列7878','data'=>$orderInfo,'order_id'=>$order_id,'activity_id'=>$orderInfo['activity_id']],'error');
        if(!$orderInfo) return false;
        if($orderInfo->status != '1') return false;
        //更新订单数据
        $updateData = [
            'status'=>'10',
            'close_time'=>time(),
            'remarks'=>'未支付订单超时自动关闭'
        ];
        $ret = \app\api\model\order\Order::where(['id'=>$order_id])->update($updateData);
        //归还库存
        if($orderInfo['activity_id']){
            // \think\Log::write(['msg'=>'测试队列返还库存','data'=>$orderInfo,'order_id'=>$order_id,'activity_id'=>$orderInfo['activity_id']],'error');
            $orderProductInfo = \app\api\model\order\OrderProduct::where('order_id',$order_id)->find();
            $backStock = \app\api\model\activity\Activity::where('id',$orderInfo['activity_id'])->setInc('stock',$orderProductInfo['number']);
        }
        if($ret){
            return true;
        }else{
            return false;    
        }
    }
    
}

  

$job->release(2); 重新调用任务 2是延迟2秒执行
$job->delete(); 删除任务

  

调用

在实际应用中调用该基类

//创建订单自动关闭任务
$jobHandlerClassName = 'app\common\library\task\OrderClose';
$jobData = ['order_id'=>$orderProductDatas['order_id']];
$jobQueueName = 'order_close';
//延迟执行
$isPushed = \think\Queue::later(30 * 60,$jobHandlerClassName, $jobData,$jobQueueName);
//立即执行
$isPushed = \think\Queue::push($jobHandlerClassName, $jobData,$jobQueueName);

两个方法,前者是(30 * 60)秒后执行,后者立即执行
注意的是
later 延迟执行 无反参 我执行成功 返回了null
push 有反参 返回随机的字符串

php think queue:listen --queue order_close

php think queue:listen

  

 

posted @ 2025-06-24 00:47  丶Gang  阅读(32)  评论(0)    收藏  举报