سؤال

لديّ تحميلات موقع وحدة تحميل NGINX ، ولكن ما زلت بحاجة إلى نقل الملفات (دعنا نقول 3-20 ميغابايت لكل منهما) إلى CDN لدينا ، ويفضل عدم تفويض ذلك إلى وظيفة الخلفية.

ما هي أفضل طريقة للقيام بذلك مع Tornado دون منع الطلبات الأخرى؟ هل يمكنني القيام بذلك في رد اتصال غير متزامن؟

هل كانت مفيدة؟

المحلول 2

تشير المشورة بشأن مجموعة Tornado Google إلى استخدام رد اتصال Async (موثق في http://www.tornadoweb.org/documentation#non-locking-asynchronous-requests) لنقل الملف إلى CDN.

تكتب وحدة تحميل NGINX الملف إلى القرص ثم تمرر المعلمات التي تصف التحميل (s) مرة أخرى إلى العرض. لذلك ، فإن الملف ليس في الذاكرة ، ولكن الوقت الذي يستغرقه القراءة من القرص - مما قد يتسبب في حظر عملية الطلب نفسها ، ولكن ليس عمليات الإعصار الأخرى ، AFAIK - لا تذكر.

ومع ذلك ، أي شيء لا يفعل بحاجة إلى يجب أن تتم معالجتها عبر الإنترنت يجب ألا تكون كذلك ، ويجب تأجيلها إلى قائمة انتظار مهمة مثل celeryd أو مشابه.

نصائح أخرى

قد تجدها مفيدة في الهندسة المعمارية الإجمالية لموقعك لإضافة خدمة قائمة انتظار الرسائل مثل الأرنب.

هذا من شأنه أن يتيح لك إكمال التحميل عبر وحدة Nginx ، ثم في معالج Tornado ، قم بنشر رسالة تحتوي على مسار الملف المحمّل والخروج. ستكون عملية منفصلة مشاهدة هذه الرسائل والتعامل مع النقل إلى CDN الخاص بك. سيكون هذا النوع من الخدمة مفيدًا للعديد من المهام الأخرى التي يمكن التعامل معها في وضع عدم الاتصال (إرسال رسائل البريد الإلكتروني ، إلخ ..). مع نمو نظامك ، يوفر لك هذا أيضًا آلية لتوسيع نطاقها عن طريق نقل معالجة قائمة الانتظار إلى آلات منفصلة.

أنا أستخدم بنية مشابهة جدًا لهذا. فقط تأكد من إضافة عملية المستهلك للرسالة إلى المشرف أو أي شيء تستخدمه لإدارة العمليات الخاصة بك.

من حيث التنفيذ ، إذا كنت في Ubuntu تثبيت RabbitMQ أمر بسيط:

sudo apt-get install rabbitmq-server

على centos w/epel مستودعات:

yum install rabbit-server

هناك عدد من روابط بيثون إلى الأرانب. بيكا هل أحدهم ويتم إنشاؤه بواسطة الموظف من lshift, ، المسؤول عن الأرانب.

أدناه قليلا من عينة من الرموز من Pika repo. يمكنك بسهولة أن تتخيل كيف ستقبل طريقة Handle_delivery رسالة تحتوي على filepath ودفعها إلى 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