2017-03-23 4 views
2

So versuche ich meine Website zu optimieren und auf jeder Seite laden und beenden ich eine Metrik (Zeit auf der Seite, IP-Adresse usw.) für die Analytik speichern. Dies sind jedoch Engpässe von angemessener Größe auf meinem Server. Wenn ich die Zeit betrachte, die benötigt wird, um die Dinge auszuführen, dauert meine gesamte Funktion ~ 1-2 ms, und dann dauert das Speichern in der DB ~ 100-200 ms. Also ist es mein Ziel, meine Funktion auszuführen und dann einen neuen Job zu versenden, der die eigentliche Speicherung der Metrik übernimmt. Auf diese Weise können alle gespeicherten Modelle in eine Warteschlange ausgelagert werden. Nachfolgend finden Sie eine Kopie meiner ArbeitLaravel 5.4 Speichern von Modellen über asynchrone Warteschlange

class SaveMetric implements ShouldQueue 
{ 
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; 
    /** 
    * Create a new job instance. 
    * 
    * @return void 
    */ 
    public function __construct() 
    { 
     // 
    } 

    /** 
    * Execute the job. 
    * 
    * @return void 
    */ 
    public function handle(Metrics $metric) 
    { 
     // 
     $metric->save(); 
    } 
} 

Dann Funktion in meinem Controller, nachdem ich alle Werte packe ich brauche ich dieses laufen

dispatch(new SaveMetric($newMetric)); 

Dies scheint zu laufen, aber scheint nicht, etwas zu tun. Fehle ich etwas? (Bearbeiten) Dies tut ~ etwas ~ Es speichert nur einen Datensatz in der Datenbank mit null in allen Feldern, als ob ich eine neue Metrik ohne Werte erstellt.

  • Ist es erforderlich, eine Warteschlange in den Jobversand zu übernehmen?
  • Muss ich einen Daemon oder etwas ähnliches ausführen, um die Dinge in der Warteschlange tatsächlich zu verarbeiten?

habe ich die Aufgabe, die Handwerker unter Verwendung der: Job-Befehl

Antwort

2

Sie ziemlich nah dran sind.

class SaveMetric implements ShouldQueue 
{ 
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; 

    protected $metric; 

    /** 
    * Create a new job instance. 
    * 
    * @param Metrics $metric 
    */ 
    public function __construct(Metrics $metric) 
    { 
     $this->metric = $metric; 
    } 

    /** 
    * Execute the job. 
    * 
    * @return void 
    */ 
    public function handle() 
    { 
     $this->metric->save(); 
    } 
} 

Nach the docs:

In diesem Beispiel beachten Sie, dass wir in der Lage waren Konstruktor ein beredtes Modell passiert direkt in den Job in der Warteschlange ist. Aufgrund der SerializeModels-Eigenschaft, die der Job verwendet, werden Eloquent-Modelle bei der Verarbeitung des Jobs ordnungsgemäß serialisiert und unserialisiert. Wenn Ihr eingereihter Job in seinem Konstruktor ein Eloquent-Modell akzeptiert, wird nur der Bezeichner für das Modell in die Warteschlange serialisiert. Wenn der Job tatsächlich bearbeitet wird, ruft das Warteschlangensystem die vollständige Modellinstanz automatisch erneut aus der Datenbank ab.

+1

Dies zusammen mit dem Entfernen von SerializesModels Merkmal hat mich mein beabsichtigtes Verhalten. – CMOS

+0

Danke! Ja, ich musste auch das Merkmal "SerializesModels" entfernen, da ich möchte, dass mein Job jede Klasse speichern kann, die mein 'BaseModel' erbt. – Ryan