php-LaravelCronSchedulerジョブが期待どおりに実行されていません
Laravel cronの問題があります。コンソールカーネルで、10分ごとにRollovercron.phpファイルにヒットし、ヒットするたびに1つの国を通過するジョブを定義しました。少なくとも100か国が配列で定義され、foreachループに従って1つずつRollovercron.phpに渡されます。 Rollovercron.phpファイルは、単一の国で実行するのに最低2時間かかります。
このcronジョブで複数の問題があります:
-
配列内の100個の要素が1つずつフェッチされないということは、「GH」国(ガーナ)が5回連続して実行され、多くの国がスキップされていることがわかります。
-
国が見つからないという問題が発生するたびに、コンポーザーの更新とキャッシュのクリアを頻繁に行います。
cronをスムーズに実行し、すべての国をフェッチする必要があります。単一の国でさえ見逃してはならず、このために常にコンポーザーの更新を行う必要はありません。
これで私を助けてください、何ヶ月もの間これのために苦労しています。
以下はKernel.phpファイルです:
<?php namespace App\Console; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; use DB; class Kernel extends ConsoleKernel { /** * The Artisan commands provided by your application. * * @var array */ protected $commands = [ \App\Console\Commands\preAlert::class, \App\Console\Commands\blCron::class, \App\Console\Commands\mainRollover::class, \App\Console\Commands\refilingSync::class, \App\Console\Commands\TestCommand::class, \App\Console\Commands\rollOverCron::class, \App\Console\Commands\FrontPageRedis::class, \App\Console\Commands\filingStatusRejectionQueue::class, \App\Console\Commands\VesselDashboardRedis::class, \App\Console\Commands\Bookingcountupdate::class, // \App\Console\Commands\Voyagetwovisit::class, ]; /** * Define the application's command schedule. * * @param \Illuminate\Console\Scheduling\Schedule $schedule * @return void */ protected function schedule(Schedule $schedule) { $countrylist=array('NL','AR','CL','EC','DE','PH','ID','TT','JM','KR','BE','VN','US','BR','CM','MG','ZA','MU','RU','DO','GT','HN','SV', 'PR','SN', 'TN', 'SI','CI','CR','GM','GN','GY','HR','LC','LR','MR','UY','KH','BD','TH','JP','MM','AT','IE','CH','LB','PY','KE','YT','TZ','MZ','NA','GQ','ME'); foreach ($countrylist as $country) { $schedule->command('rollOverCron:send ' . $country) ->everyTenMinutes() ->withoutOverlapping(); } foreach ($countrylist as $country) { $schedule->command('mainRollover:send ' . $country) ->daily() ->withoutOverlapping(); } $schedule->command('filingStatusRejectionQueue') ->hourly() ->withoutOverlapping(); $schedule->command('Bookingcountupdate') ->everyTenMinutes() ->withoutOverlapping(); $schedule->command('preAlert') ->hourly() ->withoutOverlapping(); } protected function commands() { require base_path('routes/console.php'); } } /** * Register the Closure based commands for the application. * * @return void */
答え :
解決策:
Laravelのスケジューリングは、それがどのように機能するかを知っていると役立つので、期待どおりに機能しないときにデバッグできます。これには、ソースでのダイビングが含まれます。
スケジューラでコマンドを呼び出すと、イベントが返されます。
Laravelがオーバーラップを定義するものをどのように決定するかを確認しましょう。1440分、別名24時間後に期限切れになることがわかります。
したがって、1日後、スケジュールされたアイテムが実行されていない場合、これらのスケジュールされたアイテムはスケジュールされなくなります。
ここではmutexが使用されていることがわかります。それがどこから来たのか見てみましょう。 コンストラクタで提供されているようです。
では、どのミューテックスが提供されているかを見てみましょう。 execおよびcall関数では、Schedulerコンストラクターで定義されたミューテックスが使用されます。
そこで使用されるミューテックスは、おそらくファサードとして使用されるインターフェースであり、実際の実装は、mutexName<を使用してミューテックスIDを作成するCacheSchedulingMutexである可能性が最も高いです。 /a>イベントと現在の時刻(時間と分)から。
mutexName を見ると、式とコマンドを組み合わせたIDが存在することがわかります。
要約すると、1つのスケジューラ関数で呼び出されるすべてのイベントは、メソッド呼び出しが重複していないかどうかのチェックに使用されるのと同じミューテックスを共有しますが、ミューテックスは、異なるパラメータを含む、コマンドごとに一意の識別子を生成します。時間。
スケジュールされたジョブは24時間後に期限切れになります。つまり、完了するのに2時間かかるジョブでは、1日に約12のジョブが完了します。仕事が小さい場合は多く、仕事に時間がかかる場合は少なくなります。これは、PHPがデフォルトでシングルスレッドプロセスであるためです。 最初にタスク1、次にタスク2、次にタスク3など...これは、各タスクに2時間かかる場合、12タスク後に、ジョブが1440分間実行されたためにキューに入れられたジョブが期限切れになり、新しいジョブがスケジュールされることを意味します。そしてそれは上から再び始まります。
幸いなことに、それらが同時に実行されることを確認する方法があります。
スケジュール呼び出しに->runInBackground()
を追加することをお勧めします。
$ schedule-> command('rollOverCron:send'。$ country)
-> everyTenMinutes()
-> withoutOverlapping()
{-コード-1}
-> emailOutputTo(['[email protected]'、'[email protected]']); cgm.com']);
}
同様の質問
私たちのウェブサイトで同様の質問で答えを見つけてください。