接续上一篇的queue基础使用,本例子结合延时队列来完成订单固定时间取消的流程。
环境
- ThinkPHP5.1
- supervisor
- redis
使用说明
使用的tp的queue,这里自行去composer安装对应框架的版本即可
具体流程
-
创建一个任务列表
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;
因为我还有别的导入、导出队列,所以这里可以视情况删减字段。
-
加入队列
加入锚点,我是在订单创建成功的同时,将订单同步到取消订单队列中去。
加入队列方法
//加入队列 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 = hinkQueue::later(1500, $jobClass, $exportData, $job); return $queueRes; } else { return false; } }
-
在你的job目录编写具体执行取消方法(我的是app/job/模块/cancel)
public function exec(Job $job, $params) { //1.具体的订单取消逻辑 //2.我在创建订单的时候,是不会减少库存的,所以不进行库存操作,各位在这里就可以任意发挥了 //3.成功/失败都需要返回给任务表结果,我这里是更改status字段的值,2-失败,3-成功 }
-
去你的redis中查看你的任务是否已经添加进来。
-
在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
结束
在这里延时队列取消订单就搞定了。