يمكن أن يكون تعلم الكرفس أمرًا شاقًا. على الرغم من أن وثائقها شاملة، إلا أنها تميل إلى تخطي الأساسيات.
سيحدد هذا المنشور أربعة من المفاهيم الرئيسية في Celery، ويناقش العلاقة بين Celery وKombu، ويستخدم بعض أمثلة التعليمات البرمجية لتوضيح كيف يمكن أن يكون Celery مفيدًا في التطبيقات الحقيقية. ستستخدم الأمثلة إطار عمل الويب Django ومصمم الديكور @shared_task الخاص به، لكن المفاهيم تنطبق أيضًا على Flask وFastAPI وغيرها.
ستتعرض لضغوط شديدة للعثور على مكان في وثائق Celery الحالية التي توضح بوضوح ما تعتبره وسيطًا أو خلفية، ولكن مع البحث الكافي يمكنك العثور عليه و استنتاج التعريفات.
فيما يلي المفاهيم التي يجب أن تعرفها قبل البدء باستخدام الكرفس.
المهمة هي جزء من العمل الذي ستؤديه سيليري بشكل غير متزامن (في هذا السياق، هذه كلمة خيالية تعني "ليس على الفور"). في تطبيق الويب، قد تكون إحدى المهام هي إرسال بريد إلكتروني بعد قيام المستخدم بإرسال نموذج. يمكن أن يستغرق إرسال بريد إلكتروني عدة ثوانٍ، كما أن إجبار المستخدم على انتظار إرسال بريد إلكتروني قبل إعادة التوجيه يمكن أن يجعل التطبيق يبدو بطيئًا.
يتم تحديد المهام باستخدام أدوات الديكور في الكرفس. أدناه نستخدم مصمم @shared_task لتحويل send_thank_you_email() إلى مهمة كرفس يمكن استخدامها في معالج إرسال النموذج Submit_feedback().
from config.celery import shared_task from django.core.mail import send_mail from django.shortcuts import render, redirect from feedback.forms import FeedbackForm @shared_task def send_thank_you_email(email_address): send_mail( "Thank you for your feedback!", "We appreciate your input.", "[email protected]", [email_address], ) def submit_feedback(request): if request.method == "POST": form = FeedbackForm(request.POST) if form.is_valid(): form.save() # Push the task to the broker using the delay() method. send_thank_you_email.delay(form.cleaned_data["email"]) return redirect("/thank-you/") else: form = FeedbackForm() return render(request, "feedback.html", {"form": form})
عندما يتم تعريف مهمة باستخدام الديكور في الكرفس، فإنه يضيف طريقة تأخير () إلى المهمة. يمكنك رؤية مهمة send_thank_you_email التي تستدعي طريقة التأخير () في المثال أعلاه بعد حفظ النموذج بنجاح. عندما يتم استدعاء تأخير ()، فإنه سيتم إرسال مهمة send_thank_you_email وبياناتها إلى الوسيط حيث يتم تخزينها وسيتم تنفيذها لاحقًا بواسطة عامل، وعند هذه النقطة سيقوم المستخدم يتم إرسالها عبر البريد الإلكتروني.
تصبح فائدة دفع العمل إلى Celery أكثر وضوحًا إذا كنت بحاجة إلى إرسال رسائل بريد إلكتروني إضافية بعد حفظ النموذج. على سبيل المثال، قد ترغب في إرسال بريد إلكتروني إلى فريق دعم العملاء لإبلاغهم بتلقي تعليقات جديدة. مع الكرفس، لا يضيف هذا أي وقت إضافي تقريبًا للاستجابة.
تسمح مهام الكرفس أيضًا بتكوين متقدم إضافي. في حالة فشل إرسال بريد إلكتروني، يمكنك ترميز مهمتك لإعادة المحاولة تلقائيًا وتكوين الإعدادات مثل max_retries، وretry_backoff، وretry_jitter، وما إلى ذلك.
يتضمن مسرد مقترحات تحسين الكرفس ما يلي ليقوله عن وسطاء الرسائل :
تحدد أنماط التكامل المؤسسي وسيط الرسائل باعتباره كتلة بناء معمارية يمكنها تلقي الرسائل من وجهات متعددة وتحديد الوجهة الصحيحة وتوجيه الرسالة إلى القناة الصحيحة.
لأغراضنا مع Celery، سنعتبر الوسيط "نقل الرسائل" حيث يتم تخزين المهام التي تم إنشاؤها. لا يقوم الوسطاء في الواقع بتنفيذ المهمة: هذه هي وظيفة العامل. الوسطاء هم بدلاً من ذلك المكان الذي يتم فيه تخزين المهام المجدولة في عند جدولة مهمة، و يتم سحبها من عندما يقوم العامل في النهاية بتنفيذ مهمة. الوسيط هو مكون مطلوب لكي تعمل شركة Celery، وسوف تتصل شركة Celery بوسيط واحد بالضبط.
تسرد صفحة الوسطاء والواجهات الخلفية لـ Celery بعض الوسطاء المدعومين، وهناك وسطاء تجريبيين آخرين يدعمهم غير مدرجين (مثل SQLAlchemy). تتم إدارة هؤلاء الوسطاء (أو "عمليات نقل الرسائل") بواسطة مكتبة Python التي يديرها Celery لنقل الرسائل والتي تسمى Kombu. عند البحث عن معلومات حول تكوين الوسطاء، من المفيد أحيانًا الرجوع إلى وثائق Kombu بدلاً من وثائق Celery.يتمتع بعض الوسطاء بميزات متقدمة مثل توزيع المهام والأولوية، بينما يعمل البعض الآخر كقوائم انتظار بسيطة.
عامل
worker هو مثيل لـ Celery الذي يسحب المهام من الوسيط وينفذ وظائف المهمة المحددة في تطبيق Python الخاص بك. تستطيع شركة Celery تشغيل كود Python في العاملين لديها لأن شركة Celery نفسها مكتوبة بلغة Python.
يمكن للعديد من العمال العمل في وقت واحد لتنفيذ المهام. عندما تقوم بتشغيل أمر عامل الكرفس، فإنه سيقوم بتدوير عامل لكل نواة جهاز الكمبيوتر الخاص بك بشكل افتراضي. إذا كان جهاز الكمبيوتر الخاص بك يحتوي على 16 مركزًا، فإن تشغيل عامل الكرفس سيبدأ تشغيل 16 عاملًا.إذا لم يتم تشغيل أي عامل، فسوف تتراكم الرسائل (المهام) في الوسيط حتى يتوفر العمال لتنفيذها.
الخلفية
الواجهات الخلفية:
إذا كنت تريد تتبع المهام أو تحتاج إلى قيم الإرجاع، فيجب على Celery تخزين الحالات أو إرسالها إلى مكان ما حتى يمكن استرجاعها لاحقًا. هناك العديد من الواجهات الخلفية للنتائج المضمنة للاختيار من بينها: SQLAlchemy/Django ORM، وMemcached، وRabbitMQ/QPid (rpc)، وRedis - أو يمكنك تحديد الواجهة الخاصة بك.
TLDR: الخلفية تتتبع النتائج و النتائج التي تم إرجاعها للمهام غير المتزامنة. ماذا يعني ذلك في الواقع، ومتى يمكن أن يكون مفيدًا؟
تخيل أنك تقوم بإنشاء تطبيق محاسبة في Django يمكنه إنشاء تقرير سنوي. قد يستغرق إنشاء التقرير دقائق.لمنح المستخدمين تجربة أكثر استجابة، يمكنك استخدام طلب AJAX لبدء مهمة إنشاء التقرير. يقوم هذا الطلب بإرجاع معرف المهمة، والذي يمكنه استخدامه لاستقصاء الخادم كل بضع ثوانٍ لمعرفة ما إذا كان قد تم إنشاء التقرير. بمجرد اكتمال المهمة، سيتم إرجاع معرف التقرير، والذي يمكن للعميل استخدامه لعرض رابط للتقرير عبر JavaScript.
يمكننا تنفيذ ذلك مع Celery وDjango باستخدام الكود التالي:
from celery import shared_task from django.http import JsonResponse from django.views.decorators.http import require_http_methods from accounting.models import Asset from accounting.reports import AnnualReportGenerator @shared_task def generate_report_task(year): # This could take minutes... report = AnnualReportGenerator().generate(year) asset = Asset.objects.create( name=f"{year} annual report", url=report.url, ) return asset.id @require_http_methods(["POST"]) def generate_annual_report_view(request): year = request.POST.get("year") task = generate_report_task.delay(year) return JsonResponse({"taskId": task.id}) def get_annual_report_generation_status_view(request, task_id): task = generate_report_task.AsyncResult(task_id) # The status is typically "PENDING", "SUCCESS", or "FAILURE" status = task.status return JsonResponse({"status": status, "assetId": task.result})في هذا المثال، يتم تخزين معرف الأصل الذي تم إرجاعه بواسطة generator_report_task() في
الواجهة الخلفية. تقوم الواجهة الخلفية بتخزين النتيجة و النتيجة التي تم إرجاعها. لا تقوم الواجهة الخلفية بعدم بتخزين حالة المهام التي لم تتم معالجتها بعد: لن تتم إضافتها إلا بمجرد ظهور نتيجة. المهمة التي تُرجع "معلقة" لها حالة غير معروفة تمامًا: قد لا تكون هناك مهمة مرتبطة بها موجودة. ستعرض المهام عادةً "نجاح" أو "فشل"، ولكن يمكنك رؤية جميع الحالات في مستندات حالة الكرفس.
وجود واجهة خلفية ليس مطلوبًا لـ Celery لتشغيل المهام. ومع ذلك، فهو مطلوب إذا كنت بحاجة إلى التحقق من نتيجة مهمة ما أو إرجاع نتيجة المهمة. إذا حاولت التحقق من حالة المهمة عندما لا يكون لدى Celery واجهة خلفية مهيأة، فسيتم ظهور استثناء.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3