web-dev-qa-db-ja.com

Laravelキューに入れられたジョブは、遅延があってもすぐに処理されます

私は現在、プライベートサーバーに関する個人用アプリケーション(たとえば、 Minecraft サーバー)を開発しており、サーバーのクエリに時間がかかるため、キューに入れられたジョブを実装することにしました。ただし、これらは適切に機能しておらず、遅延しても呼び出し時にすぐに実行されるため、ページリクエストで大きな遅延が発生します。

30秒の遅延ですべてのサーバーを更新するジョブを呼び出す私のHomeControllerのindex()は次のとおりです。

public function index()
{
    $servers = Server::all();

    foreach($servers as $server)
    {
        // Job Dispatch
        $job = (new UpdateServer($server->id))->delay(30);
        $this->dispatch($job);
    }
    return view('serverlist.index', compact('servers'));
}

サーバーを更新するジョブクラスは次のとおりです。

class UpdateServer extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;
    protected $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

    public function handle(){
        $server = Server::findOrFail($this->id);

        // Preparing the packet
        $test = new RAGBuffer();
        $test->addChar('255');
        $test->addChar('1');
        $test->addShort(1 | 8);

        // Finding the server
        $serverGame = new RAGServer($server->server_ip);

        // Get server information
        $status = $serverGame->sendPacket($test);

        $server->onlinePlayers = $status->getOnline();
        $server->peakPlayers = $status->getPeak();
        $server->maxPlayers = $status->getMax();

        if (!$server->save()) {
            // Error occurred
        }
    }
}

HomeControllerのindex()が実行されるたびに、ページリクエストに大幅な遅延が発生します。 Laravelの公式Webページでチュートリアルをたどり、答えを見つけようとしましたが、何も見つかりませんでした。

それで、私は何が間違っていますか?ジョブが30秒遅れてサーバーのバックグラウンドで実行されないのはなぜですか?

また、handle()は想定されていることを実行しています。サーバーにクエリを送信し、パケットを送信して、正しい情報でデータベースを更新します。

30
Micael Sousa

プロジェクトのルートディレクトリの.envファイルで使用するキュードライバーを設定する必要があります。

デフォルトでは、キュードライバーはsyncであり、これはまさにキューを即時に実行して、ユーザーが説明していることを正確に実行します。

Beanstalkedやredisなど、いくつかの異なるキュードライバーを選択できます(これが私の選択です)。 beanstalkedキューの設定について、laracasts.comに excellent freebie があります。

Laravelで利用可能なすべてのキュードライバーオプションを表示するには、 こちら を参照してください。

これが.envの例です

APP_ENV=local
APP_DEBUG=true
APP_KEY=SomeRandomString

DB_Host=localhost
DB_DATABASE=Homestead
DB_USERNAME=Homestead
DB_PASSWORD=secret

CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync      //< put the desired driver here

MAIL_DRIVER=smtp
MAIL_Host=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
30
chris p bacon

上記の変更を行っても機能しない場合は、次のようにキューファイルのデフォルト値を確認してください:dd(Config::get('queue.default'))

私にとっては、構成キャッシュをフラッシュするまで変更されませんでした:

php artisan config:clear
8

Laravel 5.7が.envファイルでQUEUE_DRIVERをQUEUE_CONNECTIONに名前変更したことに気づく前に、これは何年もの間私を狂わせていました

8
John Mellor

php artisan serveで実行している場合は、これを再起動してphp artisan serveを再度実行してください。これは何時間後それが何であるか疑問に思って試みた後私のために働きました。 :)

ローカルでテストするには、ドライバーを

QUEUE_DRIVER=database 

そしてphp artisan queue:tableを実行し、次にphp artisan migrateを実行すると、キューがデータベースに保存され、視覚的に何が起こっているのかを確認できます。

キューを実行するには、単純な実行php artisan queue:listen ..そして、artisan serveと同じように実行したままにします。

3
Rafael Milewski

確認しておいて

'default' => env('QUEUE_DRIVER', 'database'), 

config/queue.phpおよび

QUEUE_DRIVER=database 

データベースドライバーが使用されていることを確認するための.envファイル内

2
TomH

Phpunitを介してキューサービスに対してテストを実行している場合は、

<env name="QUEUE_DRIVER" value="X"/>

phpunit.xmlで、必要なキュードライバーをオーバーライドしません。

1
thephper

すべてを適切に構成した場合でも、これは発生する可能性があります。 Laravel 5.4でこの問題が発生しました。ここでは、多数のジョブを作成し、一部を遅延させ、Queue:bulk($jobs)を介してキューに追加しました。この呼び出しとQueue::Push($job)delayを完全に無視して、ジョブをすぐに処理します。

設定したとおりにジョブをキューに入れたい場合は、dispatch($job)を呼び出す必要があります。

0
Thomas

それは、遅延関数が将来の絶対日付を取るためです

UpdateServer::dispatch($server->id)->delay(now()->addSeconds(30))
0
david oyinbo

私の場合、ShouldQueueを実装し、Queueable特性を使用する必要がありました。

class CustomNotification extends Notification implements ShouldQueue{
    use Queueable;
...
0
Luca C.