私は現在、プライベートサーバーに関する個人用アプリケーション(たとえば、 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()は想定されていることを実行しています。サーバーにクエリを送信し、パケットを送信して、正しい情報でデータベースを更新します。
プロジェクトのルートディレクトリの.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
上記の変更を行っても機能しない場合は、次のようにキューファイルのデフォルト値を確認してください:dd(Config::get('queue.default'))
私にとっては、構成キャッシュをフラッシュするまで変更されませんでした:
php artisan config:clear
Laravel 5.7が.envファイルでQUEUE_DRIVERをQUEUE_CONNECTIONに名前変更したことに気づく前に、これは何年もの間私を狂わせていました
php artisan serve
で実行している場合は、これを再起動してphp artisan serve
を再度実行してください。これは何時間後それが何であるか疑問に思って試みた後私のために働きました。 :)
ローカルでテストするには、ドライバーを
QUEUE_DRIVER=database
そしてphp artisan queue:tableを実行し、次にphp artisan migrateを実行すると、キューがデータベースに保存され、視覚的に何が起こっているのかを確認できます。
キューを実行するには、単純な実行php artisan queue:listen ..そして、artisan serveと同じように実行したままにします。
確認しておいて
'default' => env('QUEUE_DRIVER', 'database'),
config/queue.phpおよび
QUEUE_DRIVER=database
データベースドライバーが使用されていることを確認するための.envファイル内
Phpunitを介してキューサービスに対してテストを実行している場合は、
<env name="QUEUE_DRIVER" value="X"/>
phpunit.xmlで、必要なキュードライバーをオーバーライドしません。
すべてを適切に構成した場合でも、これは発生する可能性があります。 Laravel 5.4でこの問題が発生しました。ここでは、多数のジョブを作成し、一部を遅延させ、Queue:bulk($jobs)
を介してキューに追加しました。この呼び出しとQueue::Push($job)
delay
を完全に無視して、ジョブをすぐに処理します。
設定したとおりにジョブをキューに入れたい場合は、dispatch($job)
を呼び出す必要があります。
それは、遅延関数が将来の絶対日付を取るためです
UpdateServer::dispatch($server->id)->delay(now()->addSeconds(30))
私の場合、ShouldQueue
を実装し、Queueable
特性を使用する必要がありました。
class CustomNotification extends Notification implements ShouldQueue{
use Queueable;
...