web-dev-qa-db-ja.com

Laravel Artisan CLIはデーモンキューワーカーを安全に停止します

多数のジョブを処理するために、完了するまでの作業量に応じて、可変数のキューワーカーを実行します。適切と思われる期間内に実行する必要がある作業を完了するために必要な数を超えるワーカーを実行する必要はありません。

現時点では、テスト目的で5つのデーモンキューワーカーを起動していますが、実稼働環境では、この数は25〜100ワーカーの可能性があります。 php artisan downフラグは、フレームワークがワーカーの起動時にのみロードされるため、--daemonを使用して最初にフレームワークをメンテナンスモードにすることで、キューワーカーを停止する必要があることを理解しています。ワーカーが再起動するまで、デプロイ中に新しいコードは有効になりません。

何らかの理由でワーカーを停止する必要がある場合は、php artisan downを使用してアプリケーションをメンテナンスモードにすることができます。ただし、アプリケーション全体をメンテナンスモードにせずにワーカーを殺したい場合があります。

ワーカーが現在のジョブの処理を続行し、アプリケーション全体をメンテナンスモードにせずに停止するような方法でワーカーを停止する安全な方法はありますか?

本質的に必要なのはphp artisan queue:stopで、これはphp artisan queue:restartのように動作しますが、ジョブが完了するとワーカーを再起動しません。

これを行うphp artisan queue:stopコマンドのようなものがあると期待していましたが、そうではないようです。

ps aux | grep phpを使用すると、ワーカーのプロセスIDを取得できます。そのようにしてプロセスを強制終了できますが、ジョブの途中でプロセスを強制終了したくありません。

ありがとう。

17
Vigs

このようなものをアプリケーションに実装しましたが、Laravel自体に組み込まれているものではありません。編集する必要があります このファイル ifブロックに別の条件を追加して、stop関数を呼び出します。これは、カスタムコマンドを実行するたびに変更されるWorkerクラスに静的変数を設定することで実行できます。あなたが作らなければならないこと(すなわちphp artisan queue:pause)またはアトミック値をチェックする(redis、memcached、APC、さらにはMySQLなどのキャッシュに設定しますが、これは、このwhileループのサイクルごとに1つのMySQLクエリがあることを意味します)同じカスタムコマンドを使用します。

4
Nikko

--daemonフラグを使用する場合、キューが空のときにワーカーを終了しないでください。

あなたが探しているのは キューのドキュメントにあります

php artisan queue:restartコマンドは、現在のジョブが完了した後、ワーカーに再起動を促します。

3
Deinumite

my Laravel=は5.6です。あなたは(pidを殺します)作業を失うことを心配する必要はありませんpcntl(extension)Laravel安全な出口

以下の部分ソースを表示します(./vendor/laravel/framework/src/Illuminate/Queue/Worker.php):

protected function listenForSignals()
{
    pcntl_async_signals(true);

    pcntl_signal(SIGTERM, function () {
        $this->shouldQuit = true;
    });

    pcntl_signal(SIGUSR2, function () {
        $this->paused = true;
    });

    pcntl_signal(SIGCONT, function () {
        $this->paused = false;
    });
}

そして、以下の私のテスト:

for($i=0; $i<100; $i++){
        pcntl_async_signals(true);

    pcntl_signal(SIGTERM, function () {
        echo 'SIGTERM';
    });

    pcntl_signal(SIGUSR2, function () {
        echo 'SIGUSR2';
    });

    pcntl_signal(SIGCONT, function () {
        echo 'SIGCONT';
    });
echo $i; 
sleep(1);
 }

あなたはそれを殺そうとすることができます

0
Zuo Zou

Laravel 5.5以降)には、Illuminate\Queue\Events\Loopingというメインワーカーループ内のdaemonShouldRun()呼び出しから起動されるIlluminate\Queue\Workerというイベントがあります。 ジョブを処理する必要がありますチェックし、falseを返すと、キューワーカーはチェックがtrueを返すまで停止します。次回チェックするまでにスリープがあり、--sleep <seconds>をqueue:workに渡すことでカスタマイズできます。コマンド。

私は現在、展開中にこの手法を使用して、ドッカーコンテナー内で実行されるワーカーを停止します。これは、ハッキングされずに提案されたqueue:restartを実行することは容易ではないためです.

0
alexkb