PHP | ThinkPHP5.1+ supervisor 延时队列取消订单

接续上一篇的queue基础使用,本例子结合延时队列来完成订单固定时间取消的流程。

环境

  • ThinkPHP5.1
  • supervisor
  • redis

使用说明

使用的tp的queue,这里自行去composer安装对应框架的版本即可

具体流程

  1. 创建一个任务列表

    CREATE TABLE `table_name`  (
      `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
      `name` varchar(200) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '任务名称',
      `message` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL COMMENT '任务消息',
      `file_type` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '文件类型',
      `type` tinyint(1) NULL DEFAULT NULL COMMENT '任务类型:1-导出,2-导入',
      `status` tinyint(1) NULL DEFAULT NULL COMMENT '任务状态,0为等待执行,1正在导出,2导出成功,3导出失败,4正在导入,5导入成功,6导入失败,7中断,8部分导入',
      `params` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL COMMENT '相关参数',
      `file_name` varchar(200) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '文件名称',
      `file_size` varchar(200) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '文件大小',
      `file_path` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '文件路径',
      `create_time` int(10) NULL DEFAULT NULL COMMENT '创建时间',
      `update_time` int(10) NULL DEFAULT NULL COMMENT '更新时间',
      `delete_time` int(10) NULL DEFAULT NULL COMMENT '删除时间',
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci COMMENT = '任务表' ROW_FORMAT = Dynamic;
    
    SET FOREIGN_KEY_CHECKS = 1;
    

    因为我还有别的导入、导出队列,所以这里可以视情况删减字段。

  2. 加入队列

    加入锚点,我是在订单创建成功的同时,将订单同步到取消订单队列中去。

    加入队列方法

    //加入队列
        protected function addCancel($status)
        {
            $task_name  = '自动取消订单';
            $filter     = "id={$status['order_id']}";
            $job        = 'Cancel';
            $where      = [];
            //convertUrlQuery  将 'id=1' 解析为  array('id'=>1)
            if ($filter) {
                $where = convertUrlQuery($filter);
            }
            $taskModel    	=   new TaskModel();	//任务表模型
            $data['name']   =   $task_name;			//添加到任务表字段参数
            $data['status'] =   0;				   //等待执行
            $data['params'] =   json_encode($where); //请求参数
            $res            =   $ietaskModel->addOrderCancelTask($data, $job);
            return $res;
        }
        
        //在任务模型中的方法,添加数据到队列中去
       /**
         * 加入取消订单队列
         * @param $data
         * @param string $job
         * @return bool
         */
        public function addOrderCancelTask($data, $job = 'Cancel')
        {
            if ($this->save($data)) {
                $exportData['task_id']  = $this->id;
                $exportData['params']   = $data['params'];
                $jobClass               = 'app\\job\\order\\' . $job .'@exec';	//具体执行方法位置
                $queueRes               = \think\Queue::later(1500, $jobClass, $exportData, $job);
                return $queueRes;
            } else {
                return false;
            }
        }
    
  3. 在你的job目录编写具体执行取消方法(我的是app/job/模块/cancel)

    public function exec(Job $job, $params)
        {
            //1.具体的订单取消逻辑
            //2.我在创建订单的时候,是不会减少库存的,所以不进行库存操作,各位在这里就可以任意发挥了
        	//3.成功/失败都需要返回给任务表结果,我这里是更改status字段的值,2-失败,3-成功
        }
    
  4. 去你的redis中查看你的任务是否已经添加进来。

    队列数据

  5. 在Linux中开启你的supervisor,在配置,启动过程中,我遇到点问题,到时候开另外一篇在说

    [program:进程名]
    process_name=%(program_name)s_%(process_num)02d
    directory=执行目录。你的网站根目录(/var/www/xxx)
    command=php think queue:work --queue Cancel --daemon
    numprocs = 3         ; 开启的进程数量
    autostart = true     ; 在 supervisord 启动的时候也自动启动
    startsecs = 5        ; 启动 5 秒后没有异常退出,就当作已经正常启动了
    autorestart = true   ; 程序异常退出后自动重启
    startretries = 3     ; 启动失败自动重试次数,默认是 3
    user = root          ; 用哪个用户启动
    redirect_stderr = true  ; 把 stderr 重定向到 stdout,默认 false
    stdout_logfile_maxbytes = 50MB  ; stdout 日志文件大小,默认 50MB
    stdout_logfile_backups = 20     ; stdout 日志文件备份数
    ; stdout 日志文件,需要手动创建目录(supervisord 会自动创建日志文件)
    stdout_logfile = /var/log/supervisord/xxx.log	;需要提前创建,不然会报错
    loglevel=info
    [supervisord]
    
    

    开启supervisor

    supervisord -c /etc/supervisord.conf

结束

在这里延时队列取消订单就搞定了。

posted @ 2020-09-01 14:11  Dan_eil  阅读(885)  评论(0编辑  收藏  举报