ホームページ  >  記事  >  PHPフレームワーク  >  Laravel がスケジュールされたタスクの繰り返し実行を防ぐ方法

Laravel がスケジュールされたタスクの繰り返し実行を防ぐ方法

步履不停
步履不停オリジナル
2019-07-03 14:37:423308ブラウズ

Laravel がスケジュールされたタスクの繰り返し実行を防ぐ方法

基本的な紹介

スケジュールされたタスクの実行には想像よりも時間がかかることがあり、問題が発生する可能性があります---現時点ではタスクが完了する前を実行すると、別の同一のタスクが実行され、タスクの重複が発生します。 たとえば、1分ごとにレポートを生成するタスクを実行すると、時間が経つとデータ量が多くなり実行時間が1分を超え、前のタスクよりも先に別のタスクが生成されてしまいます。タスクが完了し、同じタスクの実行が開始されます。

解決策

ほとんどの場合、問題はありませんが、正しいデータを確保するためにこの状況を回避する必要がある場合があります。 Laravel では、withoutOverlapping メソッドを通じてこれを処理できます。

$schedule->command('mail:send')->withoutOverlapping();

Laravel は、Console\Scheduling\Event::withoutOverlapping 属性をチェックし、値が true の場合、このタスク用にミューテックスが作成され、タスクはミューテックスを作成できる場合にのみ実行されます。

ミューテックス ロックとは何ですか?

これは私がオンラインで見つけた最も面白い説明です:

会議に参加して白熱した議論をしているとき、私は机からスクリーミング チキンを取り出します。スクリーミングチキンを持っている人だけが話すことができ、スクリーミングチキンを持っていないと話すことができません。会議の主催者に指示を求めることしかできず、スクリーミング チキンを手に入れたときにのみ話すことができ、それ以外の場合は待つことしかできません。話し終えたら、スクリーミング チキンを会議の主催者に返します。主催者は、次に話す人にスクリーミング チキンを渡します。これにより、人々がお互いに話し合うことがなくなり、自分の話す時間を確保できるようになります。

叫ぶニワトリをミューテックス ロックに、人物をスレッドに置き換えます。基本的に、ミューテックスの基本概念は理解できています。

-- https://stackoverflow.com/questions/34524/...

原理分析

Laravel が初めてタスクを実行するミューテックスロックが作成され、タスクを実行するたびにミューテックスロックが存在するかどうかがチェックされ、ミューテックスロックが存在しない場合にのみタスクが実行されます。 withoutOverlapping メソッドは次のとおりです:

public function withoutOverlapping()
{
    $this->withoutOverlapping = true;

    return $this->then(function () {
        $this->mutex->forget($this);
    })->skip(function () {
        return $this->mutex->exists($this);
    });
}

Laravel は、ミューテックスがまだ存在するタスクを無視するようにスケジュール マネージャーに指示するフィルター コールバック メソッドを作成し、完了後にクリーンアップするメソッドも作成します。タスク インスタンスのミューテックス コールバック。同時に、タスクを実行する前に、Lravel は Console\Scheduling\Event::run() メソッドで次の一連のチェックを実行します。ミューテックスはどこから来たのですか?

Console\Scheduling\Schedule

がインスタンス化されると、Laravel は

Console\Scheduling\Mutex がコンテナにバインドされているかどうかを確認し、バインドされている場合はインスタンス化されます。変更しないと、Console\Scheduling\CacheMutex

if ($this->withoutOverlapping && ! $this->mutex->create($this)) {
    return;
}
が使用されます。タスク マネージャーがイベントを登録すると、ミューテックス インスタンスも一緒に渡されます:
$this->mutex = $container->bound(Mutex::class)
                        ? $container->make(Mutex::class)
                        : $container->make(CacheMutex::class);
Laravelはデフォルトでキャッシュ実装されたミューテックスを使用しますが、自分で実装して置き換えることもできます。

ミューテックスのキャッシュ バージョン

CacheMutex クラスには、イベント ミューテックスの名前をキャッシュ キーとして使用する単純なメソッドが 3 つだけあります。その前に、マネージャーはタスクの完了時にミューテックスが確実に削除されるように実行後コールバックを登録します。これはシステム内のコマンドに対してすでに保証されている可能性があります。ただし、コールバックメソッドのタスクの場合、コールバック実行時にスクリプトが終了してしまう可能性があるため、これを回避するために、

Console\Scheduling\CallbackEvent::run()

に以下のコードを追加します。タスクが予期せず閉じられた場合、反発ロックは通常通り削除できます:

$this->events[] = new Event($this->mutex, $command);
Laravel 関連の技術記事の詳細については、

Laravel チュートリアル コラムを参照して学習してください。

以上がLaravel がスケジュールされたタスクの繰り返し実行を防ぐ方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。