我有nginx上传模块处理网站上传,但仍然需要传输文件(假设每个3-20mb)到我们的cdn,而不是将其委托给后台作业.
使用龙卷风执行此操作的最佳方法是什么,而不阻止其他请求?我可以在异步回调中执行此操作吗?
您可能会发现在站点的整体架构中添加消息队列服务(如RabbitMQ)非常有用.
这将允许您通过nginx模块完成上传,然后在tornado处理程序中,发布包含上传文件路径的消息并退出.一个单独的过程将监视这些消息并处理转移到您的CDN.这种类型的服务对于可以脱机处理的许多其他任务(发送电子邮件等)非常有用.随着系统的增长,这也为您提供了一种通过将队列处理移动到单独的计算机来扩展的机制.
我使用的架构非常类似于此.只需确保将您的消息使用者流程添加到supervisord或您用于管理流程的任何内容.
在实现方面,如果你在Ubuntu上安装RabbitMQ很简单:
sudo apt-get install rabbitmq-server
在CentOS w/EPEL存储库上:
yum install rabbit-server
RabbitMQ有许多Python绑定.Pika就是其中之一,它恰好是由负责RabbitMQ 的LShift 员工创建的.
以下是Pika回购的一些示例代码.您可以很容易地想象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