مشاركة عبر


تنسيقات متينة

تقوم وظيفة المنسق بتنسيق تنفيذ الوظائف الأخرى كسير عمل قائم على الشيفرة. تتميز وظائف المنسق بالخصائص التالية:

  • يعرفون سير عمل الوظائف باستخدام الشيفرة الإجرائية. ليست هناك حاجة إلى مخططات أو مصممين تصريحيين.
  • يمكنها استدعاء دوال أخرى بشكل متزامن وغير متزامن. يمكن حفظ المخرجات من الدوال المستدعاة إلى متغيرات محلية.
  • تم تصميمها لتكون متينة وموثوقة. يتم حفظ تقدم التنفيذ تلقائيا كنقطة تحقق عندما تستدعي await الدالة عامل or yield . الحالة المحلية لا تضيع عندما تعاد العملية أو يعيد تشغيل الجهاز الافتراضي.
  • قد تكون طويلة الأمد. العمر الافتراضي الكلي لمثيل الأوركسترا قد يكون ثوان أو أيام أو شهور، أو يمكنك ضبط النسخة لتصبح لا تنتهي أبدا.

تعطيك هذه المقالة نظرة عامة على وظائف التنسيق وكيف يمكنها مساعدتك في حل تحديات تطوير التطبيقات المختلفة.

للحصول على معلومات حول أنواع الوظائف المتاحة في تطبيق Durable Functions، راجع نموذج برمجة المهام المتطورة.

نصيحة

إذا استخدمت C# مع نموذج العامل المعزل .NET، يمكنك كتابة التنسيقات باستخدام نهج قائم على الوظائف (طرق ثابتة مع [Function] خصائص) أو نهج قائم على الفئة (الفئات التي ترث من TaskOrchestrator<TInput, TOutput>). يتطلب النهج القائم على الفئة حزمة مولد المصدر Microsoft.DurableTask.Generators ويوفر استدعاءات ذات نوع قوي. لمزيد من المعلومات، راجع الأنشطة والتنسيقات الموسيقية القائمة على الصف. أمثلة كود C# في هذا المقال تظهر كلا النهجين.

توفر مجموعات تطوير المهام المتطورة نفس قدرات التنسيق Durable Functions، لكنها تعمل كتطبيقات مستقلة مدعومة ب Durable Task Scheduler.

هوية التنسيق

كل نسخة من التنسيق لها معرف مثيل، يعرف أيضا بمعرف الحالة. افتراضيا، كل معرف حالة هو معرف فريد عالمي مولد تلقائيا (GUID). ومع ذلك، يمكن أن تكون معرفات المثيلات أيضا أي قيمة سلسلة أنشأها المستخدم. يجب أن يكون كل معرف مثيل التزامن فريدا داخل مركز المهام.

تنطبق القواعد التالية على معرفات الممثلات:

  • يجب أن يكون العدد بين 1 و100 حرف.
  • يجب ألا تبدأ ب @.
  • يجب ألا تحتوي /على ، \، #، أو ? الحروف.
  • يجب ألا تحتوي على شخصيات تحكم.

ملحوظة

استخدم معرفات المثيلات المولدة تلقائيا كلما أمكن. معرفات العينات التي ينشها المستخدم مخصصة للسيناريوهات التي يتم فيها ربط واحد لواحد بين مثيل التنسيق وكيان خارجي خاص بالتطبيق، مثل طلب شراء أو وثيقة.

ملحوظة

يمكن أن يختلف تطبيق قواعد تقييد الحروف حسب مزود التخزين الذي يستخدمه التطبيق. للمساعدة في ضمان السلوك الصحيح والتوافق، اتبع قواعد معرف المثيل السابقة.

معرف مثيل التنسيق هو معلمة مطلوبة لمعظم عمليات إدارة المثيلات. معرفات العينات مهمة أيضا للتشخيص. على سبيل المثال، تستخدمها عند البحث في بيانات تتبع التنسيق في Application Insights لأغراض استكشاف الأخطاء أو التحليلات. لهذا السبب، حفظ معرفات المثيلات المولدة في موقع خارجي يسهل الرجوع إليها لاحقا، مثل سجلات قاعدة البيانات أو التطبيقات.

معرف مثيل التنسيق هو معلمة مطلوبة لمعظم عمليات إدارة المثيلات. معرفات المثيلات مهمة أيضا للتشخيص، لذا حفظ معرفات المثيلات المولدة في موقع خارجي يسهل الرجوع إليها لاحقا، مثل قاعدة بيانات أو سجلات التطبيقات.

الموثوقيه

تستخدم وظائف المنسق نمط تصميم مصدر الأحداث للحفاظ على حالة التنفيذ بشكل موثوق. بدلا من تخزين الحالة الحالية للتنسيق مباشرة، يستخدم إطار عمل المهام الدائم مخزنا ملحقا فقط لتسجيل السلسلة الكاملة من الإجراءات التي يتخذها تنسيق الوظيفة. المتجر الإضافي فقط له العديد من الفوائد مقارنة بإلغاء حالة التشغيل الكاملة. تشمل الفوائد زيادة الأداء وقابلية التوسع والاستجابة. كما تحصل على اتساق في النهاية لبيانات المعاملات، وسجلات تدقيق كاملة، وتاريخ. تدعم مسارات التدقيق إجراءات تعويضية موثوقة.

يستخدم إطار عمل المهام الدائمة مصدر الأحداث بشكل شفاف. خلف الكواليس، تستخدم وظيفة التنسيق عامل await في C# وعامل yield في JavaScript و Python. هذه المشغلات تعود إلى موزع إطار المهام الدائم التحكم في خيط الأوركستراتور. في Java، يؤدي استدعاء .await() في مهمة إلى إعادة التحكم إلى المرسل عبر نسخة مخصصة من Throwable. ثم يقوم الموزع بإرسال أي إجراءات جديدة يقوم المنظم بجدولة الوظيفة إلى التخزين. تشمل أمثلة الإجراءات استدعاء وظيفة أو أكثر من الوظائف الفرعية أو جدولة مؤقت دائم. يقوم إجراء الالتزام الشفاف بتحديث تاريخ تنفيذ نسخة التنسيق عن طريق إضافة جميع الأحداث الجديدة إلى التخزين، تماما مثل سجل الإلحاق فقط. وبالمثل، يقوم إجراء الالتزام بإنشاء رسائل في التخزين لجدولة العمل الفعلي. في هذه المرحلة ، يمكن تفريغ وظيفة المنسق من الذاكرة.

بشكل افتراضي، يستخدم Durable Functions Azure Storage كمخزن حالة وقت تشغيل، لكن مزودي storage الآخرين مدعومون أيضا.

عندما تحتاج وظيفة التنسيق إلى مزيد من العمل (على سبيل المثال، يتم استقبال رسالة رد أو انتهاء مؤقت دائم)، يستيقظ المنسق ويعيد تنفيذ الوظيفة كاملة من البداية لإعادة بناء الحالة المحلية. أثناء إعادة التشغيل، إذا حاول الكود استدعاء دالة (أو القيام بأي عمل غير متزامن آخر)، يستشعين إطار العمل الدائم بتاريخ تنفيذ التنسيق الحالي. إذا وجد أن النشاط تم تنفيذه بالفعل وأعطى نتيجة، فإنه يعيد تشغيل نتيجة تلك الدالة، ويستمر كود المنسق في العمل. يستمر إعادة التشغيل حتى يكتمل رمز الدالة أو حتى يتم جدولة أعمال غير متزامنة جديدة.

ملحوظة

لكي يعمل نمط إعادة التشغيل بشكل صحيح وموثوق، يجب أن يكون كود وظيفة التنسيق حتميا. يمكن أن يؤدي كود التنسيق غير الحتمي إلى أخطاء في وقت التشغيل أو سلوك غير متوقع آخر. لمزيد من المعلومات حول قيود الكود لوظائف الأوركستراتور، راجع قيود كود وظائف المنسق.

ملحوظة

إذا كانت وظيفة المنسق ترسل رسائل سجل، فقد يؤدي سلوك إعادة التشغيل إلى إصدار رسائل سجل مكررة. لمعرفة سبب حدوث هذا السلوك وكيفية التعامل معه، راجع تسجيل التطبيقات.

تاريخ التنسيق

يقترن سلوك تحديد مصادر الأحداث لإطار عمل المهام الدائم ارتباطا وثيقا برمز دالة المنسق الذي تكتبه. افترض أن لديك وظيفة منسق لسلسلة النشاط، كما هو الحال في المثال التالي.

نموذج العامل المعزول
[Function("HelloCities")]
public static async Task<List<string>> Run(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    var outputs = new List<string>();

    outputs.Add(await context.CallActivityAsync<string>("SayHello", "Tokyo"));
    outputs.Add(await context.CallActivityAsync<string>("SayHello", "Seattle"));
    outputs.Add(await context.CallActivityAsync<string>("SayHello", "London"));

    // Return ["Hello Tokyo!", "Hello Seattle!", "Hello London!"].
    return outputs;
}

نموذج قائم على الطبقة (عامل معزول)

يستخدم النهج القائم على الفئة مولد المصدر ويتطلب حزمة NuGet من Microsoft.DurableTask.Generators .

using Microsoft.DurableTask;

[DurableTask]
public class HelloCities : TaskOrchestrator<object?, List<string>>
{
    public override async Task<List<string>> RunAsync(
        TaskOrchestrationContext context, object? input)
    {
        var outputs = new List<string>();

        outputs.Add(await context.CallActivityAsync<string>("SayHello", "Tokyo"));
        outputs.Add(await context.CallActivityAsync<string>("SayHello", "Seattle"));
        outputs.Add(await context.CallActivityAsync<string>("SayHello", "London"));

        // Return ["Hello Tokyo!", "Hello Seattle!", "Hello London!"].
        return outputs;
    }
}

النموذج أثناء العملية
[FunctionName("HelloCities")]
public static async Task<List<string>> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

    outputs.Add(await context.CallActivityAsync<string>("SayHello", "Tokyo"));
    outputs.Add(await context.CallActivityAsync<string>("SayHello", "Seattle"));
    outputs.Add(await context.CallActivityAsync<string>("SayHello", "London"));

    // Return ["Hello Tokyo!", "Hello Seattle!", "Hello London!"].
    return outputs;
}
using Microsoft.DurableTask;

[DurableTask]
public class HelloCities : TaskOrchestrator<object?, List<string>>
{
    public override async Task<List<string>> RunAsync(TaskOrchestrationContext context, object? input)
    {
        var outputs = new List<string>();

        outputs.Add(await context.CallActivityAsync<string>("SayHello", "Tokyo"));
        outputs.Add(await context.CallActivityAsync<string>("SayHello", "Seattle"));
        outputs.Add(await context.CallActivityAsync<string>("SayHello", "London"));

        return outputs;
    }
}

عندما يتم جدولة دالة نشاط، يحفظ إطار العمل الدائم حالة تنفيذ الدالة عند نقاط التحقق المختلفة. في كل نقطة تفتيش، يحفظ الإطار الحالة في خلفية تخزين متينة. يشار إلى هذه الحالة باسم تاريخ التوزيع الأوركسترالي.

جدول التاريخ

بشكل عام، يقوم إطار المهام الدائمة بما يلي في كل نقطة تفتيش:

  • تحفظ سجل التنفيذ في تخزين متين.
  • يقوم بإدراج الرسائل في قائمة الانتظار للوظائف التي يريد المنسق استدعاءها.
  • يقوم بإدخال رسائل لجهاز التنسيق نفسه، مثل رسائل المؤقت الدائم.

عندما يكتمل نقطة التحقق، يمكن إزالة وظيفة المنسق من الذاكرة حتى يكون هناك المزيد من العمل للقيام به.

ملحوظة

لا يوفر Azure Storage أي ضمانات معاملية حول اتساق البيانات بين تخزين الجداول وقوائم الانتظار عند حفظ البيانات. للتعامل مع الأعطال، يستخدم مزود Durable Functions Azure Storage أنماط الاتساق النهائي. تساعد هذه الأنماط في ضمان عدم فقدان البيانات إذا حدث تعطل أو فقدان الاتصال في منتصف نقطة التفتيش. قد يوفر مزودو التخزين البديلون، مثل مزود تخزين Microsoft SQL Server (MSSQL) Durable Functions ، ضمانات اتساق أقوى.

عندما تنتهي الدالة المعروضة سابقا، يبدو تاريخها مشابها للبيانات في الجدول التالي في تخزين الجدول. تم اختصار الإدخالات للتوضيح.

مفتاح التقسيم (InstanceId) نوع الحدث طابع زمني الإدخال الاسم النتيجة Status
EAE885B التنفيذبدأ 2021-05-05T18:45:28.852Z قيمة فارغة HelloCities
EAE885B المنسقبدأ 2021-05-05T18:45:32.362Z
EAE885B المهام المجدولة 2021-05-05T18:45:32.670Z قل مرحبا
EAE885B المنسقتم 2021-05-05T18:45:32.670Z
EAE885B المهمة المنجزة 2021-05-05T18:45:34.201Z """مرحبا طوكيو!"
EAE885B المنسقبدأ 2021-05-05T18:45:34.232Z
EAE885B المهام المجدولة 2021-05-05T18:45:34.435Z قل مرحبا
EAE885B المنسقتم 2021-05-05T18:45:34.435Z
EAE885B المهمة المنجزة 2021-05-05T18:45:34.763Z """مرحبا سياتل!"
EAE885B المنسقبدأ 2021-05-05T18:45:34.857Z
EAE885B المهام المجدولة 2021-05-05T18:45:34.857Z قل مرحبا
EAE885B المنسقتم 2021-05-05T18:45:34.857Z
EAE885B المهمة المنجزة 2021-05-05T18:45:34.919Z """مرحبا لندن!"
EAE885B المنسقبدأ 2021-05-05T18:45:35.032Z
EAE885B المنسقتم 2021-05-05T18:45:35.044Z
EAE885B التنفيذمكتمل 2021-05-05T18:45:35.044Z "[""مرحبا طوكيو!"",""مرحبا سياتل!","""مرحبا لندن!""]" اكتمل

تحتوي أعمدة الجداول على القيم التالية:

  • PartitionKey: معرف مثيل التوزيع الموسيقي.
  • نوع الحدث: نوع الحدث. للحصول على أوصاف تفصيلية لجميع أنواع الأحداث التاريخية، انظر Durable Task Framework History Events.
  • الطابع الزمني: الطابع الزمني العالمي المنسق للحدث التاريخي.
  • الإدخال: الإدخال بتنسيق JSON للوظيفة.
  • الاسم: اسم الدالة المستدعية.
  • النتيجة: مخرج الدالة، وتحديدا قيمة العائد الخاصة بها.

التحذير

هذا الجدول مفيد كأداة تصحيح الأخطاء، لكن قد يتغير تنسيقه ومحتواه مع تطور امتداد Durable Functions.

في كل مرة تستأنف فيها الوظيفة بعد انتظار إكمال مهمة، يعيد إطار العمل الدائم تشغيل وظيفة المنسق من الصفر. في كل إعادة تشغيل، يستشاور سجل التنفيذ لتحديد ما إذا كانت المهمة غير المتزامنة الحالية مكتملة. إذا أظهر سجل التنفيذ أن المهمة قد اكتملت بالفعل، يعيد الإطار تشغيل مخرجات تلك المهمة وينتقل إلى المهمة التالية. تستمر هذه العملية حتى يتم إعادة تشغيل تاريخ الإعدام بالكامل. بعد إعادة تشغيل سجل التنفيذ الحالي، تعاد المتغيرات المحلية إلى قيمها السابقة.

الميزات والأنماط

تصف الأقسام التالية ميزات وأنماط وظائف الموزع.

التنسيقات الفرعية

يمكن لوظائف المنسق استدعاء وظائف النشاط ، ولكن أيضا وظائف المنسق الأخرى. على سبيل المثال، يمكنك إنشاء تنسيق أكبر من مكتبة وظائف المنسق. أو يمكنك تشغيل مثيلات متعددة لدالة المنسق بالتوازي.

لمزيد من المعلومات وللحصول على أمثلة، انظر sub-orchestrations في Durable Functions (Azure Functions).

مؤقتات متينة

يمكن للأنظمة التنسيقية جدولة مؤقتات دائمة لتنفيذ التأخيرات أو لإعداد معالجة المهلة على الإجراءات غير المتزامنة. استخدم مؤقتات متينة في وظائف الأوركستراتور بدلا من واجهات برمجة التطبيقات الأصلية sleep للغة.

لمزيد من المعلومات وللحصول على أمثلة، راجع مؤقتات في Durable Functions (Azure Functions).

الأحداث الخارجية

يمكن أن تنتظر وظائف المنسق حتى تقوم الأحداث الخارجية بتحديث مثيل التزامن. ميزة Durable Functions هذه غالبا ما تكون مفيدة للتعامل مع التفاعلات البشرية أو الاستدعاءات الخارجية الأخرى.

لمزيد من المعلومات والأمثلة، راجع التعامل مع الأحداث الخارجية في Durable Functions (Azure Functions).

معالجة الأخطاء

يمكن لوظائف المنسق استخدام ميزات معالجة الأخطاء في لغة البرمجة. الأنماط الموجودة مثل try/catch مدعومة في كود التنسيق.

يمكن لوظائف المنسق أيضا إضافة نهج إعادة المحاولة إلى النشاط أو وظائف المنسق الفرعي التي تستدعيها. إذا فشل نشاط أو وظيفة منسق فرعي مع استثناء، يمكن لنهج إعادة المحاولة المحدد تأخير التنفيذ وإعادة محاولة التنفيذ تلقائيا حتى عدد محدد من المرات.

ملحوظة

إذا كان هناك استثناء غير معالج في وظيفة الموزع، ينتهي وضع التوزيع في حالة معينة Failed . لا يمكن إعادة تجربة نسخة التوزيع بعد فشلها.

لمزيد من المعلومات والأمثلة، راجع التعامل مع أخطاء في Durable Functions (Azure Functions).

الأقسام الحرجة (Durable Functions 2.x، حاليا .NET فقط)

حالات التوزيع الموسيقي تكون ذات خيط واحد، لذا ظروف السباق ليست مصدر قلق داخل التوزيع الأوركسترالي. ومع ذلك ، فإن ظروف السباق ممكنة عندما تتفاعل التنسيقات مع الأنظمة الخارجية. لتقليل ظروف السباق عند التفاعل مع الأنظمة الخارجية، يمكن لوظائف المنسق تعريف secs باستخدام طريقة LockAsync في .NET.

يعرض نموذج التعليمات البرمجية التالي دالة منسق تحدد قسما حرجا. يستخدم LockAsync الطريقة للدخول إلى القسم الحرج. تتطلب هذه الطريقة تمرير مرجع أو أكثر إلى كيان دائم، يدير حالة القفل بشكل دائم. يمكن لمثيل واحد فقط من هذه التنسيق تنفيذ التعليمات البرمجية في القسم الحرج في كل مرة.

[FunctionName("Synchronize")]
public static async Task Synchronize(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var lockId = new EntityId("LockEntity", "MyLockIdentifier");
    using (await context.LockAsync(lockId))
    {
        // Critical section. Only one orchestration can enter at a time.
    }
}

تقوم هذه الطريقة LockAsync بالحصول على الأقفال المتينة وتعيد إلى IDisposable النقطة التي تنهي القسم الحرج عند التخلص منها. يمكن استخدام هذه IDisposable النتيجة مع كتلة using للحصول على تمثيل نحوي للقسم الحرج. عندما تدخل دالة المنسق إلى قسم حرج، يمكن لمثيل واحد فقط تنفيذ كتلة التعليمات البرمجية هذه. أي حالات أخرى تحاول دخول القسم الحرج تحظر حتى يخرج المثيل السابق من القسم الحرج.

ميزة القسم الحرج مفيدة أيضا لتنسيق التغييرات على الكيانات الدائمة. لمزيد من المعلومات حول الأقسام الحرجة، راجع تنسيق الكيانات.

ملحوظة

الأقسام الحرجة متوفرة في Durable Functions 2.0. حاليا، فقط التنسيقات التشغيلية .NET قيد التنفيذ تنفذ هذه الميزة. الكيانات والأقسام الحرجة غير متوفرة بعد في Durable Functions لتنسيقات العمال المعزولة بتقنية .NET.

المكالمات إلى نقاط نهاية HTTP (Durable Functions 2.x)

وظائف الأوركستراتور غير مسموح لها بتنفيذ عمليات الإدخال/الإخراج، كما هو موضح في قيود كود وظائف الأوركستراتور. الحل النموذجي لهذا القيد هو تغليف أي كود يحتاج إلى تنفيذ عمليات الإدخال/الإخراج في دالة نشاط. غالبا ما تستخدم التوزيعات التي تتفاعل مع الأنظمة الخارجية وظائف النشاط لإجراء استدعاءات HTTP وإعادة النتائج إلى التنسيق.

لتبسيط هذا النمط الشائع، يمكن لوظائف التنسيق استخدام الطريقة CallHttpAsync لاستدعاء واجهات برمجة تطبيقات HTTP مباشرة.

نموذج العامل المعزول
[Function("CheckSiteAvailable")]
public static async Task CheckSiteAvailable(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    Uri url = context.GetInput<Uri>();

    // Make an HTTP GET request to the specified endpoint.
    DurableHttpResponse response = await context.CallHttpAsync(
        method: HttpMethod.Get,
        uri: url,
        content: null,
        retryOptions: null);

    if ((int)response.StatusCode == 400)
    {
        // Handle error codes.
    }
}

النموذج أثناء العملية
[FunctionName("CheckSiteAvailable")]
public static async Task CheckSiteAvailable(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    Uri url = context.GetInput<Uri>();

    // Make an HTTP GET request to the specified endpoint.
    DurableHttpResponse response = 
        await context.CallHttpAsync(HttpMethod.Get, url);

    if ((int)response.StatusCode == 400)
    {
        // Handle error codes.
    }
}

بالإضافة إلى دعم أنماط الطلب/الاستجابة الأساسية، تدعم الطريقة التعامل التلقائي مع أنماط استطلاع HTTP 202 غير المتزامنة الشائعة. كما يدعم المصادقة مع الخدمات الخارجية باستخدام الهويات المدارة.

لمزيد من المعلومات وأمثلة مفصلة، راجع ميزات HTTP.

ملحوظة

استدعاء نقاط نهاية HTTP مباشرة من وظائف التنسيق متوفر في Durable Functions 2.0 وما بعده.

المعايير المتعددة

لا يمكن تمرير معلمات متعددة إلى دالة نشاط مباشرة. التوصية هي تمرير مجموعة من الكائنات أو الكائنات المركبة.

نموذج العامل المعزول

في .NET، استخدم نوع مركب قابل للتسلسل، مثل سجل، لتمرير عدة معلمات.

public record CourseInfo(string Major, int UniversityYear);

[Function("GetCourseRecommendations")]
public static async Task<object> RunOrchestrator(
    [OrchestrationTrigger] TaskOrchestrationContext context)
{
    int universityYear = context.GetInput<int>();
    CourseInfo courseInfo = new("ComputerScience", universityYear);
    object courseRecommendations = await context.CallActivityAsync<object>(
        "CourseRecommendations", courseInfo);
    return courseRecommendations;
}

النموذج أثناء العملية

في .NET، استخدم نوع مركب قابل للتسلسل لتمرير عدة معلمات. العينة التالية تستخدم فئة بسيطة:

public class CourseInfo
{
    public string Major { get; set; }
    public int UniversityYear { get; set; }
}

[FunctionName("GetCourseRecommendations")]
public static async Task<object> RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var input = new CourseInfo
    {
        Major = "ComputerScience",
        UniversityYear = context.GetInput<int>()
    };

    object courseRecommendations = await context.CallActivityAsync<object>(
        "CourseRecommendations",
        input);
    return courseRecommendations;
}

في .NET، يمكنك استخدام أنواع السجلات أو المجموعات لتمرير عدة معلمات ككائن مركب واحد.

using Microsoft.DurableTask;

public record LocationInfo(string City, string State);

[DurableTask]
public class GetWeatherOrchestration : TaskOrchestrator<object?, string>
{
    public override async Task<string> RunAsync(TaskOrchestrationContext context, object? input)
    {
        var location = new LocationInfo("Seattle", "WA");
        string weather = await context.CallActivityAsync<string>("GetWeather", location);
        return weather;
    }
}

الخطوات التالية