해결된 문제:
● 시간이 오래 걸립니다.
● 각 끝에서 피드백을 위해 관련 작업 진행 상황을 검색할 수 없습니다.
● 작업을 사용자 정의한 후 결과를 피드백합니다.
● Laravel이 프로그램을 어떻게 만들 수 있는지 알려주세요. 시간 초과 기간 동안 백그라운드에서 실행됩니다. 코드가 길까요?
프로세스에 대한 간략한 설명
● 비동기 대기열을 사용하여 관련 작업 실행
● 보조 메소드를 사용하여 작업 생성/진행
● 노출된 인터페이스를 통해 관련 진행 상황 피드백
어시스턴트 클래스의 소스 코드는 다음과 같습니다. 다음과 같이
<?php // +---------------------------------------------------------------------- // | Do what we can do // +---------------------------------------------------------------------- // | Date : 2019/9/11 - 9:25 AM // +---------------------------------------------------------------------- // | Author: seebyyu <seebyyu@gmail.com> :) // +---------------------------------------------------------------------- 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'); } }
호출 프로세스 다음과 같이 e<?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'
]);
}
}
_Queue_Driver = redis 개발에 동기화 단계에서는 설치하는 것이 좋습니다. 오류 보고서에 대해 정말 불평할 수 없습니다. 문제 해결이 불편합니다. 대기열 문제 해결 참조: ● 위 코드는 완전히 제가 작성한 프로젝트를 바탕으로 작성한 것이므로 직접 복사하면 호환성 문제가 발생할 수 있습니다. ● 공유는 솔루션 아이디어에 가깝습니다. 앞으로 다른 사람들에게 도움이 되기를 바랍니다. ● 코드에 대한 최적화 아이디어나 제안 사항이 있으면 토론할 수도 있습니다. 더 많은 Laravel 관련 기술 기사를 보려면 위 내용은 백그라운드에서 장기 작업을 실행하기 위한 솔루션의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!....
/**
* 学校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())]);
}
}
....