【问题标题】:tornado - transferring a file to cdn without blockingtornado - 将文件传输到 cdn 而不阻塞
【发布时间】:2009-12-23 00:24:59
【问题描述】:

我有 nginx 上传模块处理网站上传,但仍需要将文件(假设每个 3-20mb)传输到我们的 cdn,并且不希望将其委托给后台作业。

在不阻止其他请求的情况下,使用 tornado 执行此操作的最佳方法是什么?我可以在异步回调中执行此操作吗?

【问题讨论】:

  • 我不知道社区的其他成员可以“修改”其他人的帖子。有趣。
  • @matt:是的,它更像是一个维基而不是一个论坛

标签: python cdn tornado


【解决方案1】:

您可能会发现在您网站的整体架构中添加消息队列服务(例如RabbitMQ)很有用。

这将让您通过 nginx 模块完成上传,然后在 tornado 处理程序中,发布一条包含上传文件路径的消息并退出。一个单独的过程将监视这些消息并处理传输到您的 CDN。这种类型的服务对于可以离线处理的许多其他任务(发送电子邮件等)很有用。随着系统的增长,这还为您提供了一种通过将队列处理移动到单独的机器来进行扩展的机制。

我正在使用与此非常相似的架构。只需确保将您的消息消费者进程添加到supervisord 或您用于管理进程的任何内容。

在实现方面,如果你在 Ubuntu 上安装 RabbitMQ 很简单:

sudo apt-get install rabbitmq-server

在带有 EPEL 存储库的 CentOS 上:

yum install rabbit-server

有许多 Python 绑定到 RabbitMQ。 Pika 是其中之一,它恰好是由负责 RabbitMQ 的 LShift 的 employee 创建的。

下面是来自 Pika 存储库的 sample code。您可以轻松想象 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

【讨论】:

  • 如果我使用离线/否则延迟的作业处理队列,我肯定会选择这样的东西——很可能是 celeryd+redis。但是,我更愿意在视图中处理上传,以免用户刷新显示“请稍候,我们正在处理您的上传”的页面。
  • 明白了。我上面的建议是针对流程的 staging -> cdn 部分。我同意您希望通过 nginx 处理上传到 staging 并为用户提供状态指示器。
【解决方案2】:

关于 tornado google 小组的建议指出使用异步回调(记录在 http://www.tornadoweb.org/documentation#non-blocking-asynchronous-requests)将文件移动到 cdn。

nginx 上传模块将文件写入磁盘,然后将描述上传的参数传递回视图。因此,文件不在内存中,但从磁盘读取所需的时间——这会导致请求进程阻塞自身,而不是其他龙卷风进程,afaik——可以忽略不计。

也就是说,任何不需要在线处理的东西都不应该,并且应该被推迟到像celeryd或类似的任务队列中。

【讨论】:

    猜你喜欢
    • 2023-03-22
    • 2013-11-12
    • 2010-11-03
    • 2012-10-14
    • 2021-08-28
    • 2014-04-09
    • 1970-01-01
    • 2014-07-24
    • 1970-01-01
    相关资源
    最近更新 更多