Wie führe ich einen lang laufenden Job im Hintergrund in Python aus?

8

Ich habe einen Web-Service, der lang laufende Jobs (in der Größenordnung von mehreren Stunden) ausführt. Ich entwickle dies mit Flask, Gunicorn und nginx.

Was ich mir vorstellen möchte, ist, dass die Route, die eine lange Zeit benötigt, eine Funktion hat, die einen Thread erstellt. Die Funktion gibt dann eine GUID zurück an die Route, und die Route gibt eine URL (unter Verwendung der GUID) zurück, die der Benutzer verwenden kann, um den Fortschritt zu überprüfen. Ich mache den Thread zu einem Daemon (thread.daemon = True), so dass der Thread beendet wird, wenn mein Aufrufcode (unerwartet) beendet wird.

Ist das der richtige Ansatz? Es funktioniert, aber das bedeutet nicht, dass es korrekt ist.

%Vor%     
Mark 16.12.2015, 20:58
quelle

4 Antworten

6

Der regulärere Ansatz, um ein solches Problem zu lösen, besteht darin, die Aktion aus der Basisanwendung zu extrahieren und sie außerhalb aufzurufen, wobei ein Task-Manager-System wie Sellerie .

Mit diesem Tutorial können Sie Ihre Aufgabe erstellen und sie über Ihre Webanwendung auslösen.

%Vor%

Dann können Sie ausführen:

%Vor%

Denken Sie daran, dass Sie den Mitarbeiter separat ausführen müssen:

%Vor%     
Ali Nikneshan 16.12.2015, 21:21
quelle
7

Sellerie und RQ sind übertrieben für einfache Aufgabe . Sehen Sie sich diese Dokumentation an - Ссылка

Schauen Sie sich auch an, wie Sie langlaufende Jobs im Hintergrund für die Flask-App ausführen - Ссылка

    
Denys Synashko 18.08.2016 00:49
quelle
4

Nun, obwohl Ihre Herangehensweise nicht inkorrekt ist, kann es dazu führen, dass Ihrem Programm die verfügbaren Threads ausgehen. Als Ali erwähnt, besteht ein allgemeiner Ansatz darin, Job-Warteschlangen wie RQ oder Celery zu verwenden. Sie müssen jedoch keine Funktionen extrahieren, um diese Bibliotheken zu verwenden. Für Flask empfehle ich Ihnen, Flask-RQ zu verwenden. Es ist einfach zu starten:

RQ

%Vor%

Denken Sie daran, Redis zu installieren, bevor Sie es in Ihrer Flask-App verwenden.

Und verwenden Sie einfach @Job Decorator in Ihren Flask-Funktionen:

%Vor%

Und schließlich brauchst du rqworker , um den Arbeiter zu starten:

  

rqworker

Sie können RQ-Dokumente für weitere Informationen sehen. RQ wurde für einfache, lang laufende Prozesse entwickelt.

Sellerie

Sellerie ist komplizierter, hat eine riesige Liste von Funktionen und wird nicht empfohlen, wenn Sie neu in Job-Warteschlangen und verteilten Verarbeitungsmethoden sind.

Greenlets

Greenlets haben Schalter. Lassen Sie zwischen lang laufenden Prozessen wechseln. Sie können Greenlets zum Ausführen von Prozessen verwenden. Der Vorteil ist, dass Sie Redis und andere Worker nicht benötigen, stattdessen müssen Sie Ihre Funktionen so umgestalten, dass sie kompatibel sind:

%Vor%     
Farsheed 19.12.2015 04:32
quelle
2

Ihr Vorgehen ist in Ordnung und wird vollkommen funktionieren, aber warum sollten Sie den Hintergrundarbeiter für Python-Webanwendungen neu erfinden, wenn eine allgemein akzeptierte Lösung existiert, nämlich Sellerie.

Ich würde eine Menge Tests sehen müssen, bevor ich einem Home-Rolling-Code für eine so wichtige Aufgabe vertraute.

Plus Sellerie bietet Funktionen wie die Persistenz von Aufgaben und die Möglichkeit, Mitarbeiter über mehrere Maschinen hinweg zu verteilen.

    
Robert Moskal 16.12.2015 21:11
quelle

Tags und Links