Django lange laufende asynchrone Aufgaben mit Threads / Verarbeitung

Haftungsausschluss: ich weiß, dass es mehrere ähnliche Fragen auf, SO. Ich glaube, ich habe gelesen, die meisten, wenn nicht alle von Ihnen, aber nicht eine Antwort finden auf meine eigentliche Frage (siehe später).
Auch ich weiß, dass die Verwendung von Sellerie oder anderen asynchronen queue-Systemen ist der beste Weg, um eine lange laufende Aufgaben - oder zumindest verwenden Sie einen cron-Skript verwaltet. Es gibt auch mod_wsgi doc über Prozesse und threads aber ich bin mir nicht sicher, ob ich alles richtig.

Die Frage ist:

was sind die genauen Risiken/Probleme mit der Verwendung der unten aufgeführten Lösungen gibt es? Einer von Ihnen rentabel für die lange laufende Aufgaben (ok, auch wenn Sellerie ist besser geeignet)?
Meine Frage ist eigentlich mehr Verständnis über die Interna von wsgi und python/django, als die Suche nach der besten Gesamtlösung. Probleme mit blockieren von threads, unsichere Zugriff auf Variablen, zombie, Verarbeitung, etc.

Sagen wir mal:

  1. meine "long_process" ist etwas wirklich sicher. auch wenn es nicht das ist mir egal.
  2. python >= 2.6
  3. Ich bin mit mod_wsgi im apache (wird nichts ändern mit uwsgi gunicorn oder?) im daemon-Modus

mod_wsgi conf:

WSGIDaemonProcess NAME user=www-data group=www-data threads=25
WSGIScriptAlias //path/to/wsgi.py
WSGIProcessGroup %{ENV:VHOST}

Dachte ich, dies sind die verfügbaren Optionen zum starten von separaten Prozesse (gemeint im weitesten Sinne) zu tragen, die auf eine lange andauernde Aufgabe während der Rückkehr schnell eine Antwort an den Benutzer:

os.Gabel

import os

if os.fork()==0:
    long_process()
else:
    return HttpResponse()

Teilprozess

import subprocess

p = subprocess.Popen([sys.executable, '/path/to/script.py'], 
                                    stdout=subprocess.PIPE, 
                                    stderr=subprocess.STDOUT)

(wo das Skript ist wahrscheinlich ein manage.py Befehl)

threads

import threading

t = threading.Thread(target=long_process,
                             args=args,
                             kwargs=kwargs)
t.setDaemon(True)
t.start()
return HttpResponse()

NB.

Aufgrund des Global Interpreter Lock, in CPython nur ein thread ausgeführt werden können Python-code auf einmal (auch wenn bestimmte performance-orientierte Bibliotheken könnte diese Einschränkung zu überwinden). Wenn Sie möchten, dass Ihre Anwendung zu einer besseren Nutzung der Rechenleistung von multi-core-Maschinen, die Sie verwenden sollten, die multiprocessing. Jedoch wird der Durchzug noch ein geeignetes Modell, wenn Sie mehrere I/O-bound tasks gleichzeitig.

Den Haupt-thread, schnell zurück (httpresponse). Wird die erzeugte langen thread block wsgi zu tun, etwas anderes für eine andere Anfrage?!

multiprocessing

from multiprocessing import Process

p = Process(target=_bulk_action,args=(action,objs))
p.start()
return HttpResponse()

Diese lösen sollte der thread-concurrency-Problem, sollte es nicht?


Also das sind die Optionen, die ich denken konnte. Was funktionieren würde und was nicht, und warum?

InformationsquelleAutor der Frage Stefano | 2011-11-09

Schreibe einen Kommentar