it-swarm.com.de

Laravel in die Warteschlange gestellte Jobs werden auch mit Verzögerung sofort verarbeitet

Ich entwickle gerade meine persönliche App, die sich auf private Server (z. B. Minecraft-Server) bezieht. Da das Abfragen des Servers einige Zeit in Anspruch nimmt, habe ich mich für die Implementierung von Jobs in der Warteschlange entschieden, die jedoch nicht ordnungsgemäß funktionieren. Sie werden sofort ausgeführt, wenn sie aufgerufen werden Sie werden verzögert, was zu einer massiven Latenz in der Seitenanforderung führt.

Hier ist der Index () meines HomeControllers, der den Job aufruft, um jeden Server mit einer Verzögerung von 30 Sekunden zu aktualisieren:

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'));
}

Die Jobklasse, die die Server aktualisiert, ist folgende:

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 info
       $status = $serverGame->sendPacket($test);

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

       if (!$server->save()) {
           //error ocurred
       }
   }
}

Wenn der Index des HomeControllers () ausgeführt wird, gibt es eine massive Verzögerung bei der Seitenanforderung. Ich folgte dem Tutorial auf Laravel's Official Webpage und versuchte, Antworten und nichts zu finden.

Also, was mache ich falsch? Warum wird der Job nicht um 30 Sekunden verzögert und dies dann im Hintergrund auf meinem Server ausgeführt? Danke im Voraus.

Außerdem: Das handle () macht, was es soll, fragt den Server ab, sendet Pakete und aktualisiert meine Datenbank mit den richtigen Informationen.

19
Micael Sousa

Sie müssen den Warteschlangentreiber einrichten, den Sie in der .env-Datei des Stammverzeichnisses Ihres Projekts verwenden möchten. 

Standardmäßig ist der Warteschlangentreiber sync, der genau das tut, was Sie beschreiben, und Warteschlangen sofort ausführen. 

Sie können aus verschiedenen Warteschlangentreibern wählen, z. B. beanstalked oder redis (was meine Wahl wäre). Auf laracasts.com gibt es ein exzellentes Freebie über das Einrichten einer Warteschlange mit Bohnen. 

Um alle verfügbaren Warteschlangen-Treiberoptionen in laravel anzuzeigen, schauen Sie nach hier

Hier ist ein Beispiel für .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
23
bambam

Für jemanden, der die oben genannten Änderungen vorgenommen hat und immer noch nicht funktioniert hat, überprüfen Sie den Standardwert der Warteschlangendatei wie folgt: dd(Config::get('queue.default'))

Bei mir hat sich nichts geändert, bis der Config-Cache geleert wurde:

php artisan config:clear
5

Wenn Sie mit php artisan serve laufen, starten Sie dies erneut und führen Sie php artisan serve erneut aus. Das funktionierte für mich nach Stunden, als ich mich fragte, was es war. :)

Das hat mich ewig verrückt gemacht, bis mir klar wurde, dass Laravel 5.7 QUEUE_DRIVER in QUEUE_CONNECTION in den .env-Dateien umbenannt hat

2
John Mellor

um lokal zu testen, können Sie den Treiber auf einstellen 

QUEUE_DRIVER=database 

und führe php artisan queue aus: table und dann php artisan migrate damit du deine Warteschlange in der Datenbank speichern kannst, so dass du visuell sehen könntest, was los ist.

und, um Ihre Warteschlangen auszuführen, führen Sie einfach die run php Handwerkerwarteschlange aus: listen .. und lassen Sie sie so laufen, wie Sie es mit dem Kunsthandwerksdienst tun

1
Rafael Milewski

Wenn Sie Tests mit dem Warteschlangendienst über phpunit ausführen, stellen Sie sicher, dass dies der Fall ist 

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

in phpunit.xml überschreibt den gewünschten Warteschlangentreiber nicht.

1
thephper

Sicher gehen, dass 

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

in config/queue.php und 

QUEUE_DRIVER=database 

in der .env-Datei, um sicherzustellen, dass der Datenbanktreiber verwendet wird

1
TomH

Auch wenn Sie alles richtig konfiguriert haben, kann dies passieren. Wir hatten dieses Problem mit Laravel 5.4, wo wir viele Jobs erstellt haben, einige verzögert, und sie über Queue:bulk($jobs) in die Warteschlange gestellt haben. Dieser Aufruf und auch Queue::Push($job) Ignorieren Sie delay vollständig und veranlassen Sie, dass der Job sofort verarbeitet wird.

Wenn Sie möchten, dass Ihr Job in die Warteschlange gestellt wird, wie Sie ihn konfiguriert haben, müssen Sie dispatch($job) aufrufen.

0
Thomas

Dies liegt daran, dass die Verzögerungsfunktion in der Zukunft ein absolutes Datum hat

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