thinkphp-queue 队列使用

611 阅读3分钟

简单介绍

消息队列中间件是大型系统中的重要组件,已经逐渐成为企业系统内部通信的核心手段。它具有松耦合、异步消息、流量削峰、可靠投递、广播、流量控制、最终一致性等一系列功能,已经成为异步RPC的主要手段之一。

ThinkPHP的Queue内置了 Redis、Database、Sync几种驱动,推荐使用 Redis think-queue 队列消息可以进行任务的发布、获取、执行、删除、重新发布、延迟发布、超时控制等操作

参考:www.thinkphp.cn/ext/6

这个文章更具体:blog.51cto.com/owenzhang24…

安装

composer require topthink/think-queue

安装以后会生成config/queue.php配置文件

[ 'default'=>'sync' //驱动类型,可选择 sync(默认):同步执行,database:数据库驱动,redis:Redis驱动//或其他自定义的完整的类名 ]

<?php

return [
    'default'     => 'redis',
    'connections' => [
        'sync'     => [
            'type' => 'sync',
        ],
        'database' => [
            'type'       => 'database',
            'queue'      => 'default',
            'table'      => 'queue',
            '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' => 'queue_failed',
    ],
];

如果使用mysql数据库(我用的mysql数据库测试的)

如果选择使用数据库的话需要创建数据库,两个表

-- 设置字符编码和外键检查
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- 创建 zh_queue 表
DROP TABLE IF EXISTS `zh_queue`;
CREATE TABLE `zh_queue` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `queue` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `payload` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `attempts` tinyint(3) UNSIGNED NOT NULL,
  `reserve_time` int(11) UNSIGNED NULL DEFAULT NULL,
  `available_time` int(11) UNSIGNED NOT NULL,
  `create_time` int(11) UNSIGNED NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `queue`(`queue`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '队列' ROW_FORMAT = COMPACT;

-- 创建 zh_queue_failed 表
DROP TABLE IF EXISTS `zh_queue_failed`;
CREATE TABLE `zh_queue_failed` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `connection` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `queue` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `payload` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `exception` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `fail_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '队列(失败)' ROW_FORMAT = COMPACT;

-- 恢复外键检查
SET FOREIGN_KEY_CHECKS = 1;

使用

控制器部分

<?php

namespace app\index\controller;

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

class JobController extends BaseController
{
    public function index()
    {
        //Queue::later(2,'app\common\job\ImageBatchJob', '延迟'.strval(time()),'任务名称');
        Queue::push('app\common\job\ImageBatchJob', '和风格和规范'.strval(time()), '任务名称');
        //return '已经发布任务:'.$name;
    }

}

任务部分

namespace app\job;

use think\queue\Job;

class Job1{
    
    public function fire(Job $job, $data){
    
            //....这里执行具体的任务 
            
             if ($job->attempts() > 3) {
                  //通过这个方法可以检查这个任务已经重试了几次了
             }
            
            
            //如果任务执行成功后 记得删除任务,不然这个任务会重复执行,直到达到最大重试次数后失败后,
            执行failed方法
            $job->delete();
            
            // 也可以重新发布这个任务
            $job->release($delay); //$delay为延迟时间
          
    }
    
    public function failed($data){
    
        // ...任务达到最大重试次数后,失败了
    }

}

监听任务并执行

php think queue:listen --queue 任务名称
或
php think queue:work --queue 任务名称