Frage

Ich habe das nginx Upload-Modul Website Uploads, müssen aber noch auf die Übertragung von Dateien (sagen wir mal 3-20mb jeweils) zu unserem CDN, und würde lieber nicht delegieren zu einem Hintergrund-Job.

Was ist der beste Weg, um dies mit Tornado zu tun, ohne andere Anfragen blockiert? Kann ich dies in einem Asynchron-Rückruf tun?

War es hilfreich?

Lösung 2

Beratung über die Gruppe Punkte Tornado google einen asynchronen Rückruf zu verwenden (dokumentiert unter http://www.tornadoweb.org/documentation#non-blocking-asynchronous-requests ), um die Datei in das CDN zu bewegen.

das nginx Upload-Modul schreibt die Datei auf der Festplatte und dann übergibt Parameter beschreiben den Upload (n) zurück zur Ansicht. daher ist die Datei nicht im Speicher, aber die Zeit nimmt es zu lesen scheiben die der Anforderungsprozess selbst verursachen würde zu blockieren, aber nicht anderer Tornado Prozesse, afaik-vernachlässigbar ist.

, was gesagt, alles, was nicht der Fall ist Notwendigkeit online bearbeitet werden soll, sollte nicht sein und sollte wie celeryd oder ähnlich einer Task-Warteschlange verschoben werden.

Andere Tipps

Sie können feststellen, es in der Gesamtarchitektur Ihrer Website nützlich, einen Message Queuing-Dienst wie RabbitMQ hinzufügen .

Dies würde lassen Sie den Upload über das nginx Modul abgeschlossen hat, dann in den Tornado-Handler, eine Nachricht schreibt den hochgeladenen Dateipfad und Ausgang enthält. Ein separater Prozess für diese Nachrichten zu beobachten wäre und den Transfer zu Ihrer CDN behandeln. Diese Art von Service würde für viele andere Aufgaben nützlich sein, die offline (E-Mails, etc ..) behandelt werden könnten. Als Ihr System wächst, stellt dies auch einen Mechanismus Skala von Queue-Verarbeitung auf unterschiedliche Maschinen zu bewegen.

Ich verwende eine Architektur sehr ähnlich. So stellen Sie sicher, dass Ihre Nachricht Verbraucher Prozess supervisord hinzuzufügen, oder was auch immer Sie verwenden, um Ihre Prozesse zu verwalten.

Im Hinblick auf die Umsetzung, wenn Sie auf der Installation von Ubuntu RabbitMQ sind, ist ein einfach:

sudo apt-get install rabbitmq-server

Auf CentOS w / EPEL Repositories:

yum install rabbit-server

Es gibt eine Reihe von Python-Anbindung an RabbitMQ. Pika ist einer von ihnen und geschieht es durch ein Mitarbeiter von LShift , der für RabbitMQ verantwortlich ist .

Im Folgenden finden Sie ein bisschen von Beispielcode von der Pika Repo. Sie können sich leicht vorstellen, wie die handle_delivery Methode eine Nachricht, die einen Dateipfad akzeptieren würde und schieben Sie es auf Ihrem CDN.

import sys
import pika
import asyncore

conn = pika.AsyncoreConnection(pika.ConnectionParameters(
        sys.argv[1] if len(sys.argv) > 1 else '127.0.0.1',
        credentials = pika.PlainCredentials('guest', 'guest')))

print 'Connected to %r' % (conn.server_properties,)

ch = conn.channel()
ch.queue_declare(queue="test", durable=True, exclusive=False, auto_delete=False)

should_quit = False

def handle_delivery(ch, method, header, body):
    print "method=%r" % (method,)
    print "header=%r" % (header,)
    print "  body=%r" % (body,)
    ch.basic_ack(delivery_tag = method.delivery_tag)

    global should_quit
    should_quit = True

tag = ch.basic_consume(handle_delivery, queue = 'test')
while conn.is_alive() and not should_quit:
    asyncore.loop(count = 1)
if conn.is_alive():
    ch.basic_cancel(tag)
    conn.close()

print conn.connection_close
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top