题
我有 nginx 上传模块处理站点上传,但仍然需要将文件(假设每个 3-20mb)传输到我们的 cdn,并且不想将其委托给后台作业。
在不阻止其他请求的情况下,使用龙卷风执行此操作的最佳方法是什么?我可以在异步回调中执行此操作吗?
解决方案 2
建议在龙卷风谷歌组点使用一个异步回调(在记录http://www.tornadoweb.org/documentation#non-blocking-asynchronous-requests )将文件移动到CDN。
nginx的上传模块将文件写入磁盘,然后通过描述上载(一个或多个)发送回视图参数。因此,该文件不是在存储器中,但所花费的时间从读取盘,这将导致请求过程到框本身,而不是其他龙卷风过程,AFAIK-是微不足道的。
这是说,任何不的需要的待处理网上不应该,而应推迟到像celeryd
或相似的任务队列。
其他提示
您可能会发现在站点的整体架构中添加消息队列服务(例如 RabbitMQ.
这将让您通过 nginx 模块完成上传,然后在tornado处理程序中,发布一条包含上传文件路径的消息并退出。一个单独的进程将监视这些消息并处理到 CDN 的传输。这种类型的服务对于许多其他可以离线处理的任务(发送电子邮件等)很有用。)。随着系统的增长,这还为您提供了一种通过将队列处理移动到单独的机器来进行扩展的机制。
我正在使用与此非常相似的架构。只需确保将您的消息消费者进程添加到 监督者 或任何您用来管理流程的东西。
在实现方面,如果您使用 Ubuntu,安装 RabbitMQ 很简单:
sudo apt-get install rabbitmq-server
在带有 EPEL 存储库的 CentOS 上:
yum install rabbit-server
有许多与 RabbitMQ 的 Python 绑定。 鼠兔 是其中之一,它恰好是由一个创建的 员工 的 左移, ,谁负责 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