8 Stimmen

Django Asynchrone Verarbeitung

Ich habe eine Reihe von Django-Anfragen, die einige mathematische Berechnungen ausführt (in C geschrieben und über ein Cython-Modul ausgeführt), die eine unbestimmte Menge (in der Größenordnung von 1 Sekunde) Zeit zur Ausführung nehmen kann. Außerdem müssen die Anfragen nicht auf die Datenbank zugreifen und sind alle unabhängig voneinander und von Django.

Im Moment ist alles synchron (mit Gunicorn und sync Worker-Typen), aber ich möchte dies asynchron und nicht blockierend machen. Kurz gesagt, ich würde gerne etwas tun:

  1. Empfangen der AJAX-Anfrage
  2. Zuweisung der Aufgabe an einen verfügbaren Worker (ohne Blockierung der Haupt-Django-Webanwendung)
  3. Worker führt Aufgabe in einer unbekannten Zeitspanne aus
  4. Django gibt das Ergebnis der Berechnung (eine Liste von Strings) als JSON zurück, sobald die Aufgabe abgeschlossen ist

Ich bin sehr neu zu asynchronen Django, und so meine Frage ist, was ist der beste Stack für tun dies.

Ist diese Art von Prozess etwas, wofür sich eine Aufgabenwarteschlange gut eignet? Würde jemand Tornado + Celery + RabbitMQ oder vielleicht etwas anderes empfehlen?

Vielen Dank im Voraus!

14voto

David Wolever Punkte 138377

Sellerie wäre perfekt dafür geeignet.

Da das, was Sie tun, relativ einfach ist (sprich: Sie brauchen keine komplexen Regeln darüber, wie Aufgaben weitergeleitet werden sollen), können Sie wahrscheinlich mit der Verwendung des Redis-Backends auskommen, was bedeutet, dass Sie RabbitMQ nicht einrichten/konfigurieren müssen (was meiner Erfahrung nach schwieriger ist).

Ich verwende Redis mit den meisten ein Dev-Build von Celery, und hier sind die relevanten Teile meiner Konfiguration:

\# Use redis as a queue
BROKER\_BACKEND = "kombu.transport.pyredis.Transport"
BROKER\_HOST = "localhost"
BROKER\_PORT = 6379
BROKER\_VHOST = "0"

# Store results in redis
CELERY\_RESULT\_BACKEND = "redis"
REDIS\_HOST = "localhost"
REDIS\_PORT = 6379
REDIS\_DB = "0"

Ich benutze auch django-celery was die Integration mit Django glücklich macht.

Kommentieren Sie, wenn Sie weitere spezifische Ratschläge benötigen.

0voto

konrad Punkte 3050

Da Sie planen, es asynchron zu machen (vermutlich mit etwas wie gevent), könnten Sie auch in Betracht ziehen, einen threaded/forked Backend-Webdienst für die Berechnungsarbeit zu machen.

Der asynchrone Frontend-Server könnte die gesamte leichte Arbeit übernehmen, Daten von Datenbanken abrufen, die für asynchrones Arbeiten geeignet sind (Redis oder Mysql mit einem speziellen Treiber), usw. Wenn eine Berechnung durchgeführt werden muss, kann der Frontend-Server alle Eingabedaten an den Backend-Server senden und das Ergebnis abrufen, wenn der Backend-Server mit der Berechnung fertig ist.

Da der Frontend-Server asynchron arbeitet, wird er nicht blockiert, während er auf die Ergebnisse wartet. Der Vorteil gegenüber der Verwendung von Celery ist, dass Sie das Ergebnis an den Client zurückgeben können, sobald es verfügbar ist.

client browser <> async frontend server <> backend server for computations

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X