Pregunta

Tengo los archivos del sitio nginx carga de manejo de módulo, pero todavía necesito para transferir archivos (digamos 3-20mb cada uno) a nuestra CDN, y prefieren no delegar eso a un trabajo en segundo plano.

¿Cuál es la mejor manera de hacer esto con un tornado sin bloquear otras solicitudes? ¿Puedo hacer esto en una devolución de llamada asincrónica?

¿Fue útil?

Solución 2

asesoramiento sobre los puntos de grupo tornado Google para el uso de una devolución de llamada asincrónica (documentado en http://www.tornadoweb.org/documentation#non-blocking-asynchronous-requests ) para mover el archivo a la CDN.

nginx el módulo de carga escribe el archivo en el disco y luego pasa los parámetros que describen la carga (s) volver a la vista. Por lo tanto, el archivo no está en la memoria, pero el tiempo que se tarda en leer del disco, lo cual haría que el proceso de solicitud para bloquear sí, pero no para otros procesos de tornado, que yo sepa, es despreciable.

que dijo, todo lo que no necesidad a procesar en línea no debe ser, y debe aplazarse a una cola de tareas como celeryd o similar.

Otros consejos

Puede que le resulte útil en la arquitectura general de su sitio para agregar un servicio de cola de mensajes tales como RabbitMQ .

Esto le permitiría completar la carga a través del módulo de nginx, a continuación, en el controlador de tornado, enviar un mensaje que contiene la ruta del archivo subido y salida. Un proceso separado sería ver a estos mensajes y manejar la transferencia a su CDN. Este tipo de servicio sería útil para muchas otras tareas que podrían ser manejados sin conexión (envío de correos electrónicos, etc ..). A medida que el sistema crece, esto también le proporciona un mecanismo para escalar moviendo el procesamiento de cola para máquinas separadas.

Estoy utilizando una arquitectura muy similar a esta. Sólo asegúrese de añadir su proceso de consumo mensaje a supervisord o lo que sea que está utilizando para gestionar sus procesos.

En términos de implementación, si usted está en Ubuntu instalar RabbitMQ es un simple:

sudo apt-get install rabbitmq-server

En CentOS w repositorios / Epel:

yum install rabbit-server

Hay una serie de enlaces Python a RabbitMQ. Pika es uno de ellos y que pasa a ser creado por un de href="http://www.lshift.net/" rel="noreferrer"> Mayús Iz , que es responsable de RabbitMQ .

A continuación se muestra un poco de de la Pika repo. Es fácil imaginar cómo el método handle_delivery aceptaría un mensaje que contiene una ruta de archivo y empujar a su 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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top