|
|
发表于 2025-6-19 15:30:57
|
显示全部楼层
|
本帖最后由 追影 于 2025-6-26 09:15 编辑
大米cms7.x使用异步队列(数据库版)实现实例:
使用场景:有时我们需要点击某个按钮立刻响应, 但实际需要执行一个大的任务(耗时未知或很长)才会回调.这就需要用到异步队列
1:安装依赖:
- composer require topthink/think-queue
复制代码
2:配置队列为使用数据库
3:创建数据库迁移文件
- php think queue:table
- php think queue:failed-table
- php think migrate:run
复制代码 4:创建队列任务(队列里要做的任务)
-
- namespace app\job;
- use app\base\service\foodai;
- use think\facade\config;
- use think\facade\log;
- use think\queue\job;
- use app\base\model\article as articlemodel;
- use think\facade\db;
- class pythonstudy
- {
- // 最大尝试次数(默认 3 次)
- public $tries = 2;
- // 最大异常次数(可选)
- public $maxexceptions = 2;
- public function fire(job $job, $article) {
- // 处理任务逻辑
- try {
- //处理任务
- $this->do_upload($article);
- // 任务成功处理后删除
- $job->delete();
- } catch (\exception $e) {
- // 任务失败处理
- $job->fail();
- }
- }
- public function failed($data) {
- // 任务失败回调
- echo "job failed: " . json_encode($data) . "\n";
- log::error('python学习任务失败', $data);
- }
- private function shouldupload($article)
- {
- return $article->title
- && $article->aid
- && $article->ai_pictures
- && !$article->upload_ai
- && !$article->public_price
- && !$article->isflash;
- }
- private function do_upload($article_arr){
- try {
- $article = (object)$article_arr;//习惯用object
- if (!$this->shouldupload($article)) {
- echo '验证参数不通过';
- return;
- }
- $str_pics = $article->ai_pictures;
- $company_code = $article->company_code?:$this->request->param('company_code');
- if(!$company_code) {echo('未传递company_code');return;}
- \payment\common::changedbbycompany($company_code);
- //上传数据集
- $baidu_service = new foodai();
- $r = $baidu_service->multi_study($str_pics, $article_arr,$company_code);
- if($r) {
- $article_model = new articlemodel();
- $article_model->where('aid', '=', $article->aid)->save(['upload_ai' => 1]);
- echo 'python do upload success';
- }else{
- echo 'python do upload fail';
- }
- return true;
- }catch (\exception $exception){
- echo $exception->getfile().$exception->getmessage();
- }
- return false;
- }
- }
复制代码
(5)写一个事件促发异步队列
-
- namespace app\base\event;
- use app\base\service\baidu as baiduservice;
- use think\facade\log;
- use think\facade\queue;
- class pythonai
- {
- public function handle($article)
- {
- queue::push(\app\job\pythonstudy::class,$article);
- }
- }
复制代码
(6)注册事件与触发该事件
注册全局事件 app/event.php
-
- // 事件定义文件
- return [
- 'bind' => [
- ],
- 'listen' => [
- 'appinit' => [],
- 'httprun' => [],
- 'httpend' => [],
- 'loglevel' => [],
- 'logwrite' => [],
- 'aistudy' => [
- \app\base\event\pythonai::class,
- ],
- ],
- 'subscribe' => [
- ],
- ];
复制代码 触发事件:用内置的event函数即可
- private function do_event($article){
- $article->company_code = $this->get_company_code();
- $article_arr = $article->toarray();
- //var_dump($article_arr);
- //触发事件
- event('aistudy',$article_arr);
- }
复制代码
(7)最后 计划任务 让队列跑起来
- # 以守护进程方式运行
- php think queue:work
复制代码
顺带说下centos守护进程方式运行supervisord配置如下
- [program:think-queue]
- command=php /wwwroot/hall/xunyuan/think queue:work
- directory=/wwwroot/hall/xunyuan
- autostart=true
- autorestart=true
- startretries=3
- user=nginx
- numprocs=1
- redirect_stderr=true
- stdout_logfile=/var/log/supervisor/think-queue.log
复制代码
|
|