торнадо — передача файла на cdn без блокировки

StackOverflow https://stackoverflow.com/questions/1950055

  •  21-09-2019
  •  | 
  •  

Вопрос

У меня есть модуль загрузки nginx, обрабатывающий загрузку сайтов, но мне все равно нужно передавать файлы (скажем, 3-20 МБ каждый) на нашу cdn, и я бы предпочел не делегировать это фоновому заданию.

Как лучше всего сделать это с торнадо, не блокируя другие запросы?Могу ли я сделать это в асинхронном обратном вызове?

Это было полезно?

Решение 2

совет группы Google Tornado указывает на использование асинхронного обратного вызова (задокументировано по адресу http://www.tornadoweb.org/documentation#non-blocking-asynchronous-requests), чтобы переместить файл на CDN.

Модуль загрузки nginx записывает файл на диск, а затем передает параметры, описывающие загрузку(и), обратно в представление.следовательно, файла нет в памяти, но время, необходимое для чтения с диска, которое может привести к блокировке самого процесса запроса, но не других процессов торнадо, на самом деле, незначительно.

тем не менее, все, что не нуждаться обрабатываться онлайн не должно и должно быть отложено в очередь задач, например celeryd или похожие.

Другие советы

Возможно, вам будет полезно добавить в общую архитектуру вашего сайта службу очередей сообщений, например КроликMQ.

Это позволит вам завершить загрузку через модуль nginx, затем в обработчике торнадо опубликовать сообщение, содержащее путь к загруженному файлу, и выйти.Отдельный процесс будет отслеживать эти сообщения и обрабатывать передачу в вашу CDN.Этот тип службы будет полезен для многих других задач, которые можно выполнять в автономном режиме (отправка электронных писем и т. д.).).По мере роста вашей системы это также предоставляет вам механизм масштабирования путем переноса обработки очередей на отдельные машины.

Я использую архитектуру, очень похожую на эту.Просто не забудьте добавить процесс потребителя сообщений в руководитель или что-то еще, что вы используете для управления своими процессами.

С точки зрения реализации, если вы используете Ubuntu, установка RabbitMQ проста:

sudo apt-get install rabbitmq-server

В репозиториях CentOS с EPEL:

yum install rabbit-server

Существует несколько привязок Python к RabbitMQ. Пика является одним из них, и он создан сотрудник из LShift, который отвечает за RabbitMQ.

Ниже немного образец кода из репозитория Пика.Вы можете легко представить, как метод handle_delivery примет сообщение, содержащее путь к файлу, и отправит его в вашу 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top