TP6(thinkphp6)隊列與延時隊列

 

安裝

在此我就不再略過TP6的項目創建過程了,大致就是安裝composer工具,安裝成功以後,再使用composer去創建項目即可。

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'     => 4,
            'timeout'    => 0,
            'persistent' => false,
        ],
    ],
    'failed'      => [
        'type'  => 'none',
        'table' => 'failed_jobs',
    ],
];

 

生產者

<?php
namespace app\controller;

use app\BaseController;
use think\facade\Queue;

class Index extends BaseController
{
    public function queue()
    {
        //當前任務將由哪個類來負責處理。
        //當輪到該任務時,系統將生成一個該類的實例,並默認調用其 fire 方法
        $jobHandlerClassName = 'app\Job\Order';

        //當前任務歸屬的隊列名稱,如果爲新隊列,會自動創建
        //php think queue:work --queue orderJobQueue
        //php think queue:work --queue orderJobQueue --daemon

        $jobQueueName = "orderJobQueue";

        //數組數據
        $orderData = [
            'id'      => uniqid(),
            'time'    => time(),
            'message' => 'later message83'
        ];

        //將該任務推送到消息隊列,等待對應的消費者去執行
        //這裏只是負責將數據添加到相應的隊列名稱的隊列裏,消費者與生產者並無聯繫

        //立即執行
        $isPushed = Queue::push($jobHandlerClassName, $orderData, $jobQueueName);
        //延遲10秒後執行
        //$isPushed = Queue::later(10, $jobHandlerClassName, $orderData, $jobQueueName);

        if ($isPushed !== false) {
            echo date('Y-m-d H:i:s') . " 隊列添加成功";
        } else {
            echo '隊列添加失敗';
        }
    }
}

 

消費者

<?php
namespace app\Job;

use think\facade\Log;
use think\queue\Job;

/**
 * @Title: app\task\job$Order
 * @Package package_name
 * @Description: todo(測試訂單消費者)
 * @author Jack
 */
class Order
{
    /**
     * @Title: fire
     * @Description: todo(fire方法是消息隊列默認調用的方法)
     * @param Job $job
     * @param array $data
     * @author Jack
     * @throws
     */
    public function fire(Job $job, array $data)
    {
        //有些消息在到達消費者時,可能已經不再需要執行了
        $isJobStillNeedToBeDone = $this->checkDatabaseToSeeIfJobNeedToBeDone($data);
        if(!$isJobStillNeedToBeDone){
            $job->delete();
            return;
        }
        $jobId =  $job->getJobId();
        $isJobDone = $this->orders($data, $jobId);
        if ($isJobDone) {
            //如果任務執行成功,記得刪除任務
            $job->delete();
        } else {
            //通過這個方法可以檢查這個任務已經重試了幾次了
            if ($job->attempts() > 3){
                Log::error('試了3次了');
                $job->delete();

                //也可以重新發布這個任務
                //print("<info>Hello Job will be availabe again after 2s."."</info>\n");
                //$job->release(2); //$delay爲延遲時間,表示該任務延遲2秒後再執行
            }
        }
    }

    /**
     * @Title: checkDatabaseToSeeIfJobNeedToBeDone
     * @Description: todo(有些消息在到達消費者時,可能已經不再需要執行了)
     * @param array $data
     * @return boolean
     * @author Jack
     * @throws
     */
    private function checkDatabaseToSeeIfJobNeedToBeDone($data)
    {
        return true;
    }

    /**
     * @Title: orders
     * @Description: todo(數據處理)
     * @param array $data
     * @author Jack
     * @throws
     */
    public function orders(array $data,  $jobId)
    {
        //對訂單進行數據庫操作或其他等等
        Log::info(date('Y-m-d H:i:s') . ' - data:' . json_encode($data));
        return true;
    }
}

 

服務器執行常駐命令

php think queue:work --queue orderJobQueue

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章