이 글은 laravel에 대한 관련 지식을 제공합니다. 주로 예약된 작업의 사용법과 원칙을 소개하며, 애플리케이션 시나리오에 따라 예약된 작업과 관련된 문제도 함께 살펴보겠습니다. 모든 사람.
【관련 권장사항: laravel 비디오 튜토리얼】
웹사이트 시스템에는 실행해야 할 예약된 작업이 많은 경우가 많습니다. 예를 들어, 푸시 구독 메시지, 통계 관련 데이터 등입니다. Linux는 일반적으로 예약된 작업을 설정하고 관리하기 위해 crontab을 사용합니다. 그러나 작업 수가 늘어날수록 예약된 작업을 관리하는 것이 더 번거롭고 관리 혼란이 발생하기 쉽습니다. 이 문제에 대한 라라벨의 해결책은 하나의 예약된 작업만 설정하는 것입니다. 비즈니스의 모든 예약된 작업은 이 예약된 작업에 따라 처리되고 판단되어 코드 수준에서 예약된 작업의 관리를 실현합니다.
첫 번째 crontab 구성:
* * * * * php artisan schedule:run >> /dev/null 2>&1
위는 예약된 작업이 1분마다 실행되도록 설정하는 것을 의미합니다. 특정 비즈니스 구성은 AppConsoleKernel의 Schedule 메서드에 배치됩니다:
class Kernel extends ConsoleKernel{ Protected function schedule(Schedule $schedule) { //综合数据统计 $schedule->command('complex_data_log') ->everyMinute() //每分钟执行一次(除此之外还有,每五、十、十五、三十...,不同方法设置的默认时间不同) ->withoutOverlapping() //防止重复执行 ->onOneServer() //在单台服务器上跑 ->runInBackground() //任务后台运行 //->appendOutputTo('log_path')//日志输出,默认追加 ->sendOutputTo('log_path'); //日志输出,默认覆盖先前日志 }}
Basic 원칙 :
Schedule:run 이 사양은 VendorilluminateconsoleSchedulingScheduleRunCommand 클래스에 정의되어 있습니다. 정의 형식은 일반 예약 작업과 동일합니다:
/** * The console command name. * * @var string */protected $name = 'schedule:run';
laravel이 명령을 구문 분석할 때 ScheduleRunCommand 클래스는 커널 클래스의 명령 배열과 병합됩니다. :
/** * Get the commands to add to the application. * * @return array */ protected function getCommands() { return array_merge($this->commands, [ 'Illuminate\Console\Scheduling\ScheduleRunCommand', ]); }
그래서 php artisan Schedule:run 명령은 프레임워크에 내장된 명령입니다.
명령이 시작되면 실행을 위해 기본적으로 클래스에서 핸들 메소드를 찾습니다.
/** vendor\illuminate\console\Command.php * Execute the console command. * * @param \Symfony\Component\Console\Input\InputInterface $input * @param \Symfony\Component\Console\Output\OutputInterface $output * @return mixed */protected function execute(InputInterface $input, OutputInterface $output){ return $this->laravel->call([$this, 'handle']);}
php artisan Schedule:run 명령은 Kernel::schedule에 등록된 모든 명령을 1분마다 스캔하고 명령이 해당 명령에 도달했는지 확인합니다. 실행 주기가 도착하면 실행되도록 큐에 넣습니다.
/** * Schedule the event to run every minute. * 代码每分钟执行一次 * @return $this */ public function everyMinute() { return $this->spliceIntoPosition(1, '*'); } /** * Splice the given value into the given position of the expression. * 拼接定时任务表达式 * @param int $position * @param string $value * @return $this */ protected function spliceIntoPosition($position, $value) { $segments = explode(' ', $this->expression); $segments[$position - 1] = $value; return $this->cron(implode(' ', $segments)); }
ScheduleRunCommand::handle 함수:
/** * Execute the console command. * * @return void */ public function handle() { foreach ($this->schedule->dueEvents($this->laravel) as $event) { if (! $event->filtersPass($this->laravel)) { continue; } $this->runEvent($event); } }
작업 중복 방지:
때로는 단일 예약 작업의 실행 시간이 너무 깁니다. 다음 실행 시간, 마지막 실행 작업이 아직 완료되지 않았습니다. 이때 작업 중복을 피하기 위해 WithoutOverlapping() 메서드를 사용할 수 있습니다. WithoutOverlapping 메소드에서 해당 작업을 잠급니다(onOneServer 메소드도 마찬가지입니다):
public function create(Event $event){ return $this->cache->store($this->store)->add( $event->mutexName(), true, $event->expiresAt );}
해당 작업 잠금을 얻은 경우에만 작업을 실행할 수 있습니다:
/** * Run the given event. * 运行任务 * @param \Illuminate\Contracts\Container\Container $container * @return void */ public function run(Container $container) { if ($this->withoutOverlapping && ! $this->mutex->create($this)) { return; } //判断是否是后台运行 $this->runInBackground ? $this->runCommandInBackground($container) : $this->runCommandInForeground($container); }
작업 백그라운드 실행:
예약된 작업 이후 순서대로 실행되는 경우 이전 작업의 실행 시간이 너무 길어서 다음 작업의 실행 시간에 영향을 미치게 되므로 runInBackground 메서드를 사용하여 작업을 백그라운드로 실행하여 실행할 수 있습니다. 셸에서 &의 역할:
/** * Build the command for running the event in the background. * 构建定时任务后台运行语句 * @param \Illuminate\Console\Scheduling\Event $event * @return string */ protected function buildBackgroundCommand(Event $event) { $output = ProcessUtils::escapeArgument($event->output); $redirect = $event->shouldAppendOutput ? ' >> ' : ' > '; $finished = Application::formatCommandString('schedule:finish').' "'.$event->mutexName().'"'; return $this->ensureCorrectUser($event, '('.$event->command.$redirect.$output.' 2>&1 '.(windows_os() ? '&' : ';').' '.$finished.') > ' .ProcessUtils::escapeArgument($event->getDefaultOutput()).' 2>&1 &' ); }
제외 위 방법에서는 Laravel의 예약된 작업을 사용하여 셸 명령을 호출할 수도 있습니다:
$schedule->exec('node /home/forge/script.js')->daily();
예약을 위해 클로저를 사용할 수도 있습니다:
$schedule->call(function () { DB::table('recent_users')->delete();})->daily();
원하는 경우 사용 방법에 대해 더 자세히 알고 싶으시면 Laravel의 문서를 확인하세요:
https:/ /laravelacademy.org/post/19517.html
[관련 권장 사항: laravel 비디오 튜토리얼]
위 내용은 laravel 예약 작업 사용법 및 원리에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!