php中文网最新课程

每日17点准时技术干货分享

解决的问题:

● 耗时较长

● 各端无法调取相关任务进度进行反馈

● 自定义任务过后反馈结果

● 请教下,Laravel 如何让程序在后台执行超长时间的代码?

流程简述

● 使用异步队列执行相关任务

● 使用助手方法进行任务 / 进度创建

● 通过暴露接口反馈相关进度

助手类源码如下

<?php // +----------------------------------------------------------------------// | Do what we can do// +----------------------------------------------------------------------// | Date  : 2019/9/11 - 9:25 AM// +----------------------------------------------------------------------// | Author: seebyyu  :)// +----------------------------------------------------------------------namespace App\Lib\Support;trait MissionFrom{    /**     * 标记前缀 模块名称#业务模块#板块标记     *     * @var string     */    public $prefix = 'school:task:default';    /**     * 任务详情     * @var array     */    public $original = [];    /**     * Redis 链接     *     * The Redis factory implementation.     *     * @var \Illuminate\Redis\Connections\Connection     */    protected $redis;    /**     * 任务存在有效期     *     * @var int     */    protected $seconds = 600;    /**     * 创建任务     *     * @param string $sheet     * @param int $len 总长度     * @return string     */    public function createTask($sheet = '', $len = 100){        $sheet = $sheet ?: $this->sheet();        $detail = [            //  开始时间            'begin' => time(),            //  标记号            'sheet' => $sheet,            //  总长度            'total_len' => $len,            //  当前长度            'schedule' => 0        ];        //  主体信息        $this->connect()->setex($this->prefix. ':'. $sheet, $this->seconds, serialize($detail));        //  初始化任务进度        $this->connect()->setex($this->prefix. ':schedule:'. $sheet, $this->seconds, 1);        return $sheet;    }    /**     * 设置任务内容     *     * @param $sheet     * @param $value     * @return MissionFrom     */    public function setTaskContent($sheet, $value){        if( $this->connect()->exists($this->prefix. ':'. $sheet)){            $this->connect()->setex($this->prefix. ':content:'. $sheet, $this->seconds, serialize($value));        }        return $this;    }    /**     * 获取任务内容     *     * @param $sheet     * @return MissionFrom     */    public function getTaskContent($sheet){        return empty($data = $this->connect()->get($this->prefix. ':content:'. $sheet)) ? null : unserialize($data);    }    /**     * 设置任务前缀     *     * @param string $prefix     * @return $this     */    public function setPrefix($prefix = ''){        $this->prefix = 'school:task:'. ($prefix ?: 'default');        return $this;    }    /**     * 任务详情     *     * @param string $sheet     * @return array     */    public function taskDetail($sheet = ''){        $detail = $this->connect()->get($key = ($this->prefix. ':'. $sheet));        if( !empty($detail)){            $this->original = array_merge( unserialize($detail), [                'schedule' => (int)$this->getSchedule($sheet),                'content' => $this->getTaskContent($sheet)            ]);        }        return (array) $this->original;    }    /**     * 进度递增     *     * @param string $sheet     * @return int     */    public function increments($sheet = ''){        $inc = 0;        if( !empty($detail = $this->taskDetail($sheet)) &&            $detail['schedule'] < $detail['total_len']){            $inc = $this->connect()->incr($this->prefix. ':schedule:'. $sheet);        }        return $detail['schedule'] ?? $inc;    }    /**     * 获取任务进度     *     * @param string $sheet     * @return string     */    public function getSchedule($sheet = ''){        return $this->connect()->exists($key = ($this->prefix. ':schedule:'. $sheet)) ? $this->connect()->get($key) : 0;    }    /**     * 生成任务单号     */    private static function sheet(){        return md5(\Hash::make(date('YmdHis')));    }    /**     * 所有任务进度     *     * @return array     */    public function taskAll(){        $task_group_list = [];        //  分组        foreach( (array)$this->connect()->keys('school:task:*') as $task) {            if( count($task_item = explode(':', $task)) == 4){                list($model, $model_name, $business, $key) = $task_item;                $task_group_list[$business][] = $this->setPrefix($business)->taskDetail($key);            }        }        return $task_group_list;    }    /**     * @return \Illuminate\Foundation\Application|mixed     */    public function connect(){        return app('redis.connection');    }}

调用过程如下

<?php namespace App\Jobs;use App\Lib\Support\MissionFrom;use Illuminate\Bus\Queueable;use Illuminate\Queue\SerializesModels;use Illuminate\Queue\InteractsWithQueue;use Illuminate\Contracts\Queue\ShouldQueue;use Illuminate\Foundation\Bus\Dispatchable;/** * Excel 导入 * * Class importExcel * @package App\Jobs */class importExcel implements ShouldQueue{    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MissionFrom;    /**     * 任务运行的超时时间。     *     * @var int     */    public $timeout = 300;    /**     * @var string     */    public $sheet;    /**     * importExcel constructor.     * @param $sheet     */    public function __construct($sheet = ''){        $this->sheet = $sheet;    }    /**     * Execute the job.     *     * @return void     */    public function handle(){        //  自定义业务前缀        $prefix = 'export_students';        //  创建任务进度        $this->sheet = $this->setPrefix($prefix)->createTask($this->sheet, 20);        //  开始执行任务        echo '任务开始:'. $this->sheet. "\n";        for ($i = 1; $i <= 20; $i++){            //  延时模拟长时间任务            sleep(rand(1, 2));            //  进度 +1            echo '任务进度:'. ($this->setPrefix($prefix)->increments($this->sheet)). "\n";        }        //  追加结果 任何类型        $this->setPrefix($prefix)->setTaskContent($this->sheet, [            'url' => 'http://www.baidu.com'        ]);    }}

控制器部分

....    /**     * 学校pc端后台任务进度列表     *     * @return array     */    public function duties(){        if( empty($key = request('key'))){            $key = md5(\Hash::make(date('YmdHis')));            //  创建任务            $this->dispatch(new importExcel($key));            return $key;        }else{            //  查询单条任务信息            //  $this->setPrefix('export_students')->taskDetail($key);            return success(['data' => array_merge([                //  导出每餐记录列表                'meal_records' => [],                //  每日记录列表                'daily_records' => [],                //  其他记录列表                'other_records' => [],                //  照片库                'photo_gallery' => [],                //  采购计划                'purchasing_plan' => [],                //  凭证记录                'voucher_records' => [],                //  食材库                'ingredient_records' => [],                //  导入学生                'import_students' => [],                //  导出学生                'export_students' => []            ], $this->taskAll())]);        }    }    ....

达到的效果

注意事项

QUEUE_DRIVER=sync 变更为 redis

开发阶段强烈建议把 horizon 这玩意儿装上,Laravel 自带的报错异常我实在无力吐槽,不方便排错.

队列排错参考下一篇文章:

Laravel 队列:如何查看队列报错信息?

最后

● 代码上面的业务完全根据我自身项目编写,直接照搬 可能会引起不兼容。

● 分享 更多的是一种解决思路,希望能帮到后面的小伙伴。

● 如果对代码 有什么优化思路 或者 建议 也可以探讨下。

-END-

声明:本文选自「 php中文网 」,搜索「 phpcnnew 」即可关注!

laravel windows 下queue能长时间执行吗_后台执行超长时间任务解决方案相关推荐

  1. Windows下自动同步工具SyncToy的使用与定时执行部署

    最近因为需要用到一个自动同步两台虚拟机的工具,在网上找了许多资料,刚开始是觉得GoodSync这个不错,界面美观,功能完善易用,可定时执行等,但是这款软件是收费的,而且winserver下要使用企业版 ...

  2. windows隐藏CMD窗口,使jar程序在后台执行

    一.准备jar文件.安装好jdk(自定义) 二.编写.bat脚本,并运行 .bat是windows下的批处理文件. 编写bat脚本的步骤如下: 1.创建txt文件,填写内容如下 @echo off i ...

  3. java编译执行与解释执行混合_编译执行与解释执行的区别

    解释执行 由解释器根据输入的数据当场执行而不生成任何目标程序. 解释执行程序是高级语言翻译程序的一种,它将源语言(如VASIC)书写的源程序作为输入,解释一句后就提交给计算机执行一句,并不生成目标程序 ...

  4. windows下c/c++创建Java虚拟机加载可执行jar包

    一般的,我们使用java.exe或者javaw.exe来执行我们的java应用程序.但是实际上这两个可执行程序只是java虚拟机的启动器,使用java.exe将会创建一个控制台窗口用于输出,而java ...

  5. windows下对hid设备interrupt端口读写_读《汇编语言》第三版 第十四章 端口

    我们知道,各种存储器都和CPU的地址线,数据线,控制线相连.CPU在操控它们的时候,把他们都当作内存来对待,把它们总地看做一个若干存储器单元组成的逻辑存储器,这个逻辑存储器称为内存地址空间. 在PC系 ...

  6. windows下客户端连接上马上会断开连接_浅尝Java NIO与Tomcat简单连接调优

    P本文使用jdk1.8.0_45spring boot 2.1.4.RELEASE 涉及源码都放在https://github.com/sabersword/Nio 前因 这周遇到一个连接断开的问题, ...

  7. windows下修改tomcat的startup.bat脚本文件后台运行

    1.修改startup.bat文件 rem Get remaining unshifted command line arguments and save them in the set CMD_LI ...

  8. r软件时间序列分析论文_高度比较的时间序列分析-一篇论文评论

    r软件时间序列分析论文 数据科学 , 机器学习 (Data Science, Machine Learning) In machine learning with time series, using ...

  9. 计算机Windows10熄屏时间怎么调节,电脑熄屏时间怎么调节_电脑熄屏时间

    2016-12-20 16:03:26 你好,你的显示器上有菜单键,你按一下找一下亮度和灰度调节,或者按一下auto键试试, 还有如果显示器没问题的话,那就需要进控制面板里找,显卡的调试程序,那里面有 ...

最新文章

  1. Linux-shell-完全详解
  2. spring boot注释_使用Spring Boot和注释支持配置Spring JMS应用程序
  3. T-SQL中的透视和逆透视
  4. linux 下运行 jar包 java.lang.ClassNotFoundException: 解决办法
  5. [原创]java WEB学习笔记35:java WEB 中关于绝对路径 和相对路径问题
  6. C++类库Pugixml与rapidxml性能评测
  7. C++ new关键字分析
  8. 老中医根治python编码问题2
  9. 台式计算机功率图片,【图片】台式机电源别随便买!教你如何选择合适功率的电脑电源!_电脑吧_百度贴吧...
  10. Pro Android学习笔记(一五五) 传感器(5) 磁场传感器和方位(上)
  11. 微信小程序本地图片处理--按屏幕尺寸插入图片
  12. 403错误(已解决)
  13. 2010页游报告:开测222款31款停运
  14. 校园网连接后,浏览器打不开登录界面可能的一种解决方法
  15. 1_一些文献中的英文解释和用法整理
  16. SDWebImage 加载图片流程
  17. vue使用百度地图3.0,使用JavaScriptAPI版,聚合点,个性化地图切换卫星地图
  18. 在Word和OneNote中插入数学公式
  19. ToC产品和ToB产品的区别To C/To B/To G分别是什么
  20. 如何树立正确的人生观、价值观、世界观?

热门文章

  1. Studio 3T:MongoDB SQL探究
  2. c#利用SWIG调用c++dll学习总结【转】
  3. CHM乱码解决方案!
  4. 电子邮件传输算法-Base64
  5. 修改tomcat控制台title的方法
  6. shell脚本--判断输入的ip是否正确
  7. SOCK开发之---TCP/IP简介
  8. nginx配置详解1
  9. Web安全实践(6)web应用剖析之信息提炼
  10. 哀悼与感动同在[转载]