接續上一篇的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 = \think\Queue::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
結束
在這里延時隊列取消訂單就搞定了。