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%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% 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:
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 ist komplizierter, hat eine riesige Liste von Funktionen und wird nicht empfohlen, wenn Sie neu in Job-Warteschlangen und verteilten Verarbeitungsmethoden sind.
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%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.
Tags und Links python multithreading nginx flask