大米CMS官网论坛,大米站长联盟,大米站长之家,大米开发者社区

 找回密码
 注册大米会员

QQ登录

只需一步,快速开始

一键js接入直播
查看: 789|回复: 0
打印 上一主题 下一主题

大米cms7.x使用异步队列(数据库)实现,当然您也可以用redis

[复制链接]

549

主题

827

帖子

8632

积分

超级版主

Rank: 8Rank: 8

积分
8632

授权用户商城金牌VIP

跳转到指定楼层
楼主
发表于 2025-6-19 15:30:57 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 追影 于 2025-6-26 09:15 编辑

大米cms7.x使用异步队列(数据库版)实现实例:
使用场景:有时我们需要点击某个按钮立刻响应, 但实际需要执行一个大的任务(耗时未知或很长)才会回调.这就需要用到异步队列

1:安装依赖:
  1. composer require topthink/think-queue
复制代码

2:配置队列为使用数据库


3:创建数据库迁移文件
  1. php think queue:table
  2. php think queue:failed-table
  3. php think migrate:run
复制代码
4:创建队列任务(队列里要做的任务)

  1. <?php

  2. namespace app\job;

  3. use app\base\service\FoodAi;
  4. use think\facade\Config;
  5. use think\facade\Log;
  6. use think\queue\Job;
  7. use app\base\model\Article as ArticleModel;
  8. use think\facade\Db;

  9. class PythonStudy
  10. {

  11.     // 最大尝试次数(默认 3 次)
  12.     public $tries = 2;

  13.     // 最大异常次数(可选)
  14.     public $maxExceptions = 2;
  15.     public function fire(Job $job, $article) {
  16.         // 处理任务逻辑
  17.         try {
  18.             //处理任务
  19.             $this->do_upload($article);
  20.             // 任务成功处理后删除
  21.             $job->delete();
  22.         } catch (\Exception $e) {
  23.             // 任务失败处理
  24.             $job->fail();
  25.         }
  26.     }

  27.     public function failed($data) {
  28.         // 任务失败回调
  29.         echo "Job failed: " . json_encode($data) . "\n";
  30.         Log::error('python学习任务失败', $data);
  31.     }

  32.     private function shouldUpload($article)
  33.     {
  34.         return $article->title
  35.             && $article->aid
  36.             && $article->ai_pictures
  37.             && !$article->upload_ai
  38.             && !$article->public_price
  39.             && !$article->isflash;
  40.     }



  41.     private function do_upload($article_arr){
  42.         try {
  43.         $article = (object)$article_arr;//习惯用object
  44.         if (!$this->shouldUpload($article)) {
  45.             echo '验证参数不通过';
  46.             return;
  47.         }
  48.         $str_pics = $article->ai_pictures;
  49.         $company_code = $article->company_code?:$this->request->param('company_code');
  50.         if(!$company_code) {echo('未传递company_code');return;}
  51.         \payment\Common::changeDbByCompany($company_code);
  52.         //上传数据集
  53.         $baidu_service = new FoodAi();
  54.         $r = $baidu_service->multi_study($str_pics, $article_arr,$company_code);
  55.         if($r) {
  56.             $article_model = new ArticleModel();
  57.             $article_model->where('aid', '=', $article->aid)->save(['upload_ai' => 1]);
  58.             echo 'python do upload success';
  59.         }else{
  60.             echo 'python do upload fail';
  61.         }

  62.         return true;
  63.         }catch (\Exception $exception){
  64.             echo $exception->getFile().$exception->getMessage();
  65.         }
  66.         return false;
  67.     }


  68. }
复制代码

(5)写一个事件促发异步队列
  1. <?php

  2. namespace app\base\event;

  3. use app\base\service\Baidu as BaiduService;
  4. use think\facade\Log;
  5. use think\facade\Queue;

  6. class PythonAi
  7. {
  8.     public function handle($article)
  9.     {
  10.         Queue::push(\app\job\PythonStudy::class,$article);
  11.     }
  12. }
复制代码

(6)注册事件与触发该事件


注册全局事件 app/event.php
  1. <?php
  2. // 事件定义文件
  3. return [
  4.     'bind'      => [
  5.     ],
  6.     'listen'    => [
  7.         'AppInit'  => [],
  8.         'HttpRun'  => [],
  9.         'HttpEnd'  => [],
  10.         'LogLevel' => [],
  11.         'LogWrite' => [],
  12.         'AiStudy' => [
  13.             \app\base\event\PythonAi::class,
  14.         ],

  15.     ],

  16.     'subscribe' => [
  17.     ],
  18. ];
复制代码
触发事件:用内置的event函数即可
  1.     private function do_event($article){
  2.         $article->company_code = $this->get_company_code();
  3.         $article_arr = $article->toArray();
  4.         //var_dump($article_arr);
  5.         //触发事件
  6.         event('AiStudy',$article_arr);
  7.     }
复制代码



(7)最后 计划任务 让队列跑起来
  1. # 以守护进程方式运行
  2. php think queue:work
复制代码


顺带说下centos守护进程方式运行supervisord配置如下
  1. [program:think-queue]
  2. command=php /wwwroot/hall/xunyuan/think queue:work
  3. directory=/wwwroot/hall/xunyuan
  4. autostart=true
  5. autorestart=true
  6. startretries=3
  7. user=nginx
  8. numprocs=1
  9. redirect_stderr=true
  10. stdout_logfile=/var/log/supervisor/think-queue.log
复制代码




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册大米会员

本版积分规则

QQ|小黑屋|大米CMS社区 ( 蜀ICP备11002200号-2

Powered by 大米CMS

© 2010-2020 大米CMS Inc.

快速回复 返回顶部 返回列表