Pergunta

Eu tenho os uploads do site de manuseio do módulo de upload nginx, mas ainda preciso transferir arquivos (digamos 3-20 MB cada) para a nossa CDN e prefere não delegar isso a um trabalho de fundo.

Qual é a melhor maneira de fazer isso com tornado sem bloquear outros pedidos? Posso fazer isso em um retorno de chamada assíncrona?

Foi útil?

Solução 2

Conselhos sobre o Tornado Google Group apontam para usar um retorno de chamada assíncrono (documentado em http://www.tornadoweb.org/documentation#non-blocking-asncronse-requests) para mover o arquivo para o CDN.

O módulo de upload nginx grava o arquivo no disco e depois passa os parâmetros que descrevem o (s) upload (s) de volta à visualização. Portanto, o arquivo não está na memória, mas o tempo necessário para ler em disco - que causaria o processo de solicitação, mas não outros processos de tornado, Afaik - é insignificante.

Dito isto, qualquer coisa que não precisar a ser processado online não deve ser e deve ser adiado para uma fila de tarefas como celeryd ou similar.

Outras dicas

Você pode achar útil na arquitetura geral do seu site para adicionar um serviço de fila de mensagens, como RabbitMQ.

Isso permitiria concluir o upload através do módulo Nginx e, no manipulador de tornados, publicar uma mensagem que contém o caminho e a saída do arquivo carregado. Um processo separado seria assistir a essas mensagens e lidar com a transferência para o seu CDN. Esse tipo de serviço seria útil para muitas outras tarefas que poderiam ser tratadas offline (enviando e -mails, etc.). À medida que seu sistema cresce, isso também fornece um mecanismo para escalar, movendo o processamento da fila para separar máquinas.

Estou usando uma arquitetura muito semelhante a isso. Apenas certifique -se de adicionar sua mensagem ao processo do consumidor a Supervisor Ou tudo o que você estiver usando para gerenciar seus processos.

Em termos de implementação, se você estiver no Ubuntu, a instalação do RabbitMQ é simples:

sudo apt-get install rabbitmq-server

Em Centos com repositórios EPEL:

yum install rabbit-server

Existem várias ligações de Python ao RabbitMQ. Pika é um deles e é criado por um empregado do LSHIFT, que é responsável pelo RabbitMQ.

Abaixo está um pouco de Código de amostra do repo Pika. Você pode imaginar facilmente como o método do handle_delivery aceitaria uma mensagem contendo um filepath e o empurraria para o seu 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top