التشخيصات في Durable Functions في Azure

هناك العديد من الخيارات لتشخيص المشكلات مع Durable Functions. بعض هذه الخيارات هي نفسها بالنسبة للوظائف العادية وبعضها فريدة من نوعها لـ Durable Functions.

Application Insights

Application Insights هو الطريقة الموصى بها للقيام بالتشخيصات والمراقبة في Azure Functions. وينطبق الشيء نفسه على Durable Functions. للحصول على نظرة عامة حول كيفية الاستفادة من Application Insights في تطبيق الوظائف الخاص بك، راجع مراقبة Azure Functions.

يقوم Azure Functions Durable Extension أيضاً بإصدار أحداث التعقب التي تسمح لك بتعقب التنفيذ الشامل للتنسيق. يمكن العثور على أحداث التعقب هذه والاستعلام عنها باستخدام أداة Application Insights Analytics في مدخل Azure.

بيانات التعقب

يؤدي كل حدث دورة حياة لمثيل تنسيق إلى حدث تعقب تتم كتابته إلى مجموعة التعقبات في Application Insights. يحتوي هذا الحدث على حمولة customDimensions مع عدة حقول. يتم إلحاق أسماء الحقول كلها بـ prop__.

  • hubName: اسم مركز المهام الذي يتم فيه تشغيل التنسيقات الخاصة بك.
  • appName: اسم تطبيق الوظائف. يفيد هذا الحقل عندما يكون لديك تطبيقات وظائف متعددة تشارك نفس مثيل Application Insights.
  • slotName: فتحة التوزيع التي يتم فيها تشغيل تطبيق الوظائف الحالي. يفيد هذا الحقل عند استخدام فتحات التوزيع لإصدار التنسيقات الخاصة بك.
  • functionName: اسم المُنسق أو وظيفة النشاط.
  • functionType: نوع الوظيفة، مثل المُنسق أو النشاط.
  • instanceId: المعرف الفريد لمثيل التنسيق.
  • الحالة: حالة تنفيذ دورة حياة المثيل. تتضمن القيم الصالحة ما يلي:
    • مجدول: تمت جدولة الوظيفة للتنفيذ ولكن لم يتم بدء تشغيلها بعد.
    • مبدوء: بدأ تشغيل الوظيفة ولكن لم يتم انتظارها أو إكمالها بعد.
    • منتظر: قام المُنسق بجدولة بعض العمل وينتظر أن يكتمل.
    • الاستماع: يستمع المنسق إلى إعلام بأحداث خارجي.
    • مكتمل: تم إكمال الوظيفة بنجاح.
    • فشل: فشل المثيل مع وجود خطأ.
  • السبب: بيانات إضافية مرتبطة بحدث التعقب. على سبيل المثال، إذا كان المثيل ينتظر إعلام بأحداث خارجي، يشير هذا الحقل إلى اسم الحدث الذي ينتظره. إذا فشلت وظيفة، سيحتوي هذا الحقل على تفاصيل الخطأ.
  • isReplay: قيمة منطقية تشير إلى ما إذا كان حدث التعقب للتنفيذ المعاد أم لا.
  • extensionVersion: إصدار ملحق Durable Task. معلومات الإصدار هي بيانات هامة بشكل خاص عند الإبلاغ عن الأخطاء المحتملة في الملحق. قد تقوم المثيلات طويلة الأمد بالإبلاغ عن إصدارات متعددة في حالة حدوث تحديث أثناء تشغيله.
  • sequenceNumber: رقم تسلسل التنفيذ لحدث. يساعد دمج الطابع الزمني على ترتيب الأحداث حسب وقت التنفيذ. لاحظ أنه ستتم إعادة تعيين هذا الرقم إلى الصفر إذا كان المضيف يعيد تشغيل أثناء تشغيل المثيل، لذلك من المهم الفرز الدائم حسب الطابع الزمني أولاً، ثم حسب sequenceNumber.

يمكن تكوين إسهاب بيانات التعقب التي تم إصدارها إلى Application Insights في logger القسم (الوظائف 1.x) أو logging (الوظائف 2.0) للملف host.json.

الوظائف 1.0

{
    "logger": {
        "categoryFilter": {
            "categoryLevels": {
                "Host.Triggers.DurableTask": "Information"
            }
        }
    }
}

الدوال 2.0

{
    "logging": {
        "logLevel": {
            "Host.Triggers.DurableTask": "Information",
        },
    }
}

بشكل افتراضي، يتم إصدار كافة أحداث تعقب غير مرتبطة بإعادة التشغيل. يمكن تقليل حجم البيانات عن طريق تعيين Host.Triggers.DurableTask إلى "Warning" أو "Error" الذي يتم فيه إصدار أحداث تعقب الحالة فقط للمواقف الاستثنائية. لتمكين إصدار أحداث إعادة تشغيل التنسيق المطول، قم بتعيين logReplayEvents إلى trueفي ملف التكوين host.json.

إشعار

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

لا يتم تسجيل المدخلات والمخرجات من وظائف المُنسق والنشاط والكيان بشكل افتراضي. يوصى بهذا السلوك الافتراضي لأن مدخلات ومخرجات التسجيل قد تزيد من تكاليف Application Insights. قد تحتوي حمولات مدخلات ومخرجات الوظيفة أيضاً على معلومات حساسة. بدلاً من ذلك، يتم تسجيل عدد وحدات البايت لمدخلات ومخرجات الوظائف بدلاً من الحمولات الفعلية بشكل افتراضي. إذا كنت تريد ملحق Durable Functions أن يقوم بتسجيل حمولات الإدخال والإخراج الكاملة، قم بتعيين traceInputsAndOutputs الخاصية إلى trueفي ملف التكوينhost.json.

الاستعلام عن مثيل واحد

يظهر الاستعلام التالي بيانات التعقب التاريخية لمثيل واحد لتنسيق وظيفة تسلسل الترحيب. تمت كتابته باستخدام Kusto Query Language. يقوم بتصفية تنفيذ إعادة التشغيل بحيث يتم عرض مسار التنفيذ المنطقي فقط. يمكن ترتيب الأحداث عن طريق الفرز حسب timestamp وsequenceNumber كما هو موضح في الاستعلام أدناه:

let targetInstanceId = "ddd1aaa685034059b545eb004b15d4eb";
let start = datetime(2018-03-25T09:20:00);
traces
| where timestamp > start and timestamp < start + 30m
| where customDimensions.Category == "Host.Triggers.DurableTask"
| extend functionName = customDimensions["prop__functionName"]
| extend instanceId = customDimensions["prop__instanceId"]
| extend state = customDimensions["prop__state"]
| extend isReplay = tobool(tolower(customDimensions["prop__isReplay"]))
| extend sequenceNumber = tolong(customDimensions["prop__sequenceNumber"])
| where isReplay != true
| where instanceId == targetInstanceId
| sort by timestamp asc, sequenceNumber asc
| project timestamp, functionName, state, instanceId, sequenceNumber, appName = cloud_RoleName

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

قام مثيل واحد لـ Application Insights بطلب الاستعلام

الاستعلام عن ملخص المثيل

يعرض الاستعلام التالي حالة كافة مثيلات التنسيق التي تم تشغيلها في نطاق زمني محدد.

let start = datetime(2017-09-30T04:30:00);
traces
| where timestamp > start and timestamp < start + 1h
| where customDimensions.Category == "Host.Triggers.DurableTask"
| extend functionName = tostring(customDimensions["prop__functionName"])
| extend instanceId = tostring(customDimensions["prop__instanceId"])
| extend state = tostring(customDimensions["prop__state"])
| extend isReplay = tobool(tolower(customDimensions["prop__isReplay"]))
| extend output = tostring(customDimensions["prop__output"])
| where isReplay != true
| summarize arg_max(timestamp, *) by instanceId
| project timestamp, instanceId, functionName, state, output, appName = cloud_RoleName
| order by timestamp asc

النتيجة هي قائمة معرفات المثيل وحالة وقت التشغيل الحالي.

الاستعلام عن مثيل واحد لـ Application Insights

تسجيل Durable Task Framework

سجلات ملحق Durable مفيدة لفهم سلوك منطق التنسيق الخاص بك. ومع ذلك، لا تحتوي هذه السجلات دائماً على معلومات كافية لتتبع أخطاء مشكلات الأداء والموثوقية على مستوى إطار العمل. بدءاً من v2.3.0 لملحق Durable، السجلات التي تم إصدارها بواسطة Durable Task Framework الأساسي متوفرة أيضاً للمجموعة.

عند النظر إلى DTFx، من المهم أن نفهم أن محرك DTFx يتكون من مكوين: محرك الإرسال الأساسي (DurableTask.Core) وواحد من العديد من موفري التخزين المدعومين (تستخدم Durable Functions DurableTask.AzureStorage افتراضياً، ولكن تتوفر الخيارات الأخرى).

  • DurableTask.Core: تنفيذ التنسيق الأساسي وسجلات الجدولة منخفضة المستوى وبيانات تتبع الاستخدام.
  • DurableTask.AzureStorage: سجلات الخلفية الخاصة بموفر حالة Azure Storage. تتضمن هذه السجلات تفاعلات مفصلة مع قوائم الانتظار الداخلية والكائنات الثنائية كبيرة الحجم وجداول التخزين المستخدمة لتخزين حالة التنسيق الداخلية وجلبها.
  • DurableTask.Netherite: سجلات الخلفية الخاصة بموفر تخزين Netherite، في حالة التمكين.
  • DurableTask.SqlServer: سجلات الخلفية الخاصة بموفر التخزين Microsoft SQL (MSSQL)، في حالة التمكين.

يمكنك تمكين هذه السجلات عن طريق تحديث القسم logging/logLevel لملف تطبيق الوظائف الخاص بك host.json. يوضح المثال التالي كيفية تمكين سجلات التحذير والخطأ من كل من DurableTask.Core وDurableTask.AzureStorage:

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "DurableTask.AzureStorage": "Warning",
      "DurableTask.Core": "Warning"
    }
  }
}

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

إشعار

بالنسبة لتطبيقات الإنتاج، يوصى بتمكين DurableTask.Core وموفر التخزين المناسب (على سبيل DurableTask.AzureStorage) باستخدام عامل التصفية "Warning". عوامل تصفية الإسهاب العليا مثل "Information" مفيدة جداً لتصحيح أخطاء مشكلات الأداء. ومع ذلك، يمكن أن تكون أحداث السجل هذه ذات حجم كبير ويمكن أن تزيد بشكل ملحوظ من تكاليف تخزين البيانات لـ Application Insights.

يظهر الاستعلام Kusto التالي كيفية الاستعلام عن سجلات DTFx. الجزء الأكثر أهمية من الاستعلام هو where customerDimensions.Category startswith "DurableTask" حيث إنه يقوم بتصفية النتائج إلى سجلات في الفئات DurableTask.Core وDurableTask.AzureStorage.

traces
| where customDimensions.Category startswith "DurableTask"
| project
    timestamp,
    severityLevel,
    Category = customDimensions.Category,
    EventId = customDimensions.EventId,
    message,
    customDimensions
| order by timestamp asc 

والنتيجة هي مجموعة من السجلات التي كتبها موفري سجل Durable Task Framework.

نتائج الاستعلام عن DTFx لـ Application Insights

لمزيد من المعلومات حول أحداث السجل المتوفرة، راجع وثائق تسجيل Durable Task Framework المنظمة على GitHub.

تسجيل التطبيق

من المهم أن تضع في اعتبارك سلوك إعادة تشغيل المنسق عند كتابة السجلات مباشرة من وظيفة المنسق. على سبيل المثال، ضع في اعتبارك وظيفة المنسق التالية:

[FunctionName("FunctionChain")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context,
    ILogger log)
{
    log.LogInformation("Calling F1.");
    await context.CallActivityAsync("F1");
    log.LogInformation("Calling F2.");
    await context.CallActivityAsync("F2");
    log.LogInformation("Calling F3");
    await context.CallActivityAsync("F3");
    log.LogInformation("Done!");
}

بيانات السجل الناتجة سوف تبدو شيئاً مثل الإخراج التالي:

Calling F1.
Calling F1.
Calling F2.
Calling F1.
Calling F2.
Calling F3.
Calling F1.
Calling F2.
Calling F3.
Done!

إشعار

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

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

[FunctionName("FunctionChain")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context,
    ILogger log)
{
    if (!context.IsReplaying) log.LogInformation("Calling F1.");
    await context.CallActivityAsync("F1");
    if (!context.IsReplaying) log.LogInformation("Calling F2.");
    await context.CallActivityAsync("F2");
    if (!context.IsReplaying) log.LogInformation("Calling F3");
    await context.CallActivityAsync("F3");
    log.LogInformation("Done!");
}

بدءا من Durable Functions 2.0، فإن وظائف المنسق .NET لديها الخيار لإنشاء ILogger الذي يقوم تلقائياً بتصفية عبارات السجل أثناء إعادة التشغيل. يتم إجراء التصفية التلقائية باستخدام واجهة برمجة التطبيقات IDurableOrchestrationContext.CreateReplaySafeLogger(ILogger).

[FunctionName("FunctionChain")]
public static async Task Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context,
    ILogger log)
{
    log = context.CreateReplaySafeLogger(log);
    log.LogInformation("Calling F1.");
    await context.CallActivityAsync("F1");
    log.LogInformation("Calling F2.");
    await context.CallActivityAsync("F2");
    log.LogInformation("Calling F3");
    await context.CallActivityAsync("F3");
    log.LogInformation("Done!");
}

إشعار

أمثلة C# السابقة هي لـ Durable Functions 2.x. بالنسبة إلى Durable Functions 1.x، يتعين عليك استخدام DurableOrchestrationContext بدلاً من IDurableOrchestrationContext. لمزيدٍ من المعلومات حول الاختلافات بين الإصدارات، راجع مقالة إصدارات Durable Functions.

مع التغييرات المذكورة مسبقاً، يكون إخراج السجل كما يلي:

Calling F1.
Calling F2.
Calling F3.
Done!

حالة مخصصة

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

[FunctionName("SetStatusTest")]
public static async Task SetStatusTest([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    // ...do work...

    // update the status of the orchestration with some arbitrary data
    var customStatus = new { completionPercentage = 90.0, status = "Updating database records" };
    context.SetCustomStatus(customStatus);

    // ...do more work...
}

إشعار

مثال C# السابق هو لـ Durable 2.x. بالنسبة إلى Durable Functions 1.x، يتعين عليك استخدام DurableOrchestrationContext بدلاً من IDurableOrchestrationContext. لمزيدٍ من المعلومات حول الاختلافات بين الإصدارات، راجع مقالة إصدارات Durable Functions.

في أثناء تشغيل التنسيق، يمكن للعملاء الخارجيين إحضار هذه الحالة المخصصة:

GET /runtime/webhooks/durabletask/instances/instance123?code=XYZ

سيحصل العملاء على الاستجابة التالية:

{
  "runtimeStatus": "Running",
  "input": null,
  "customStatus": { "completionPercentage": 90.0, "status": "Updating database records" },
  "output": null,
  "createdTime": "2017-10-06T18:30:24Z",
  "lastUpdatedTime": "2017-10-06T19:40:30Z"
}

تحذير

حمولة الحالة المخصصة محدودة بـ 16 كيلوبايت لنص UTF-16 JSON لأنها تحتاج إلى أن تكون قادرة على الاحتواء في عمود Azure Table Storage. يمكنك استخدام موقع تخزين خارجي إذا كنت بحاجة إلى حمولة أكبر.

التتبع الموزّع

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

إشعار

يتطلب التتبع الموزع V2 وظائف دائمة v2.12.0 أو أحدث. أيضا، التتبع الموزع V2 في حالة معاينة وبالتالي لا يتم وضع علامة على بعض أنماط Durable Functions. على سبيل المثال، لا يتم وضع أدوات لعمليات الكيانات الدائمة ولن تظهر التتبعات في Application Insights.

إعداد التتبع الموزع

لإعداد التتبع الموزع، يرجى تحديث host.json وإعداد مورد Application Insights.

host.json

"durableTask": {
  "tracing": {
    "distributedTracingEnabled": true,
    "Version": "V2"
  }
}

Application Insights

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

فحص التتبعات

في مورد Application Insights، انتقل إلى Transaction Search. في النتائج، تحقق من Request والأحداث Dependency التي تبدأ ببادئات محددة ل Durable Functions (على سبيل المثال orchestration:، activity:، وما إلى ذلك). سيؤدي تحديد أحد هذه الأحداث إلى فتح مخطط جانت الذي سيعرض التتبع الموزع من طرف إلى طرف.

مخطط جانت يعرض Application Insights Distributed Trace.

استكشاف الأخطاء وإصلاحها

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

التصحيح

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

  • إعادة التشغيل: تقوم وظائف Orchestrator بانتظام بإعادة التشغيل عند تلقي مدخلات جديدة. يعني هذا السلوك أن التنفيذ المنطقي الفردي لوظيفة منسق يمكن أن يؤدي إلى الوصول إلى نفس نقطة التوقف عدة مرات، خاصة إذا تم تعيينها في وقت مبكر في التعليمة البرمجية للوظيفة.
  • انتظار: عندما تتم مواجهة await في وظيفة منسق، فإنه ينتج عنه التحكم مرة أخرى إلى مرسل Durable Task Framework. إذا كانت هذه هي المرة الأولى التي تتم فيها مواجهة await معين، لا يتم استئناف المهمة المقترنة أبداً. نظراً لأن المهمة لا تُستأنف أبداً، فإن تخطي الانتظار (F10 في Visual Studio) غير محتمل. إن تخطي الانتظار يعمل فقط عند إعادة تشغيل مهمة.
  • مهلة المراسلة: تستخدم Durable Functions داخلياً رسائل قائمة الانتظار لدفع تنفيذ وظائف المنسق والنشاط والكيان. في بيئة متعددة الأجهزة الظاهرية، قد يؤدي اقتحام تصحيح الأخطاء لفترات طويلة من الوقت إلى قيام جهاز ظاهري آخر بالتقاط الرسالة، مما يؤدي إلى تنفيذ مكرر. يوجد هذا السلوك أيضاً لوظائف مشغل قائمة الانتظار العادية، ولكن من المهم الإشارة إليه في هذا السياق نظراً لأن قوائم الانتظار عبارة عن تفاصيل تنفيذ.
  • إيقاف وبدء: الرسائل في وظائف Durable تستمر بين جلسات تتبع الأخطاء. إذا قمت بإيقاف تصحيح الأخطاء وإنهاء عملية المضيف المحلي أثناء تنفيذ وظيفة دائمة، قد تقوم هذه الوظيفة بإعادة التنفيذ تلقائياً في جلسة تتبع أخطاء مستقبلية. يمكن أن يكون هذا السلوك مربكاً عندما لا يكون متوقعاً. استخدام مركز مهام جديد أو مسح محتويات مركز المهام بين جلسات تصحيح الأخطاء إحدى التقنيات لتجنب هذا السلوك.

تلميح

عند تعيين نقاط التوقف في وظائف المنسق، إذا كنت تريد فقط التوقف عن التنفيذ غير المرتبط بإعادة التشغيل، فيمكنك تعيين نقطة توقف شرطية لا تنقطع إلا إذا كانت قيمة "إعادة التشغيل" هي false.

التخزين

بشكل افتراضي، تخزن Durable Functions الحالة في Azure Storage. يعني هذا السلوك أنه يمكنك فحص حالة التنسيق باستخدام أدوات مثل Microsoft Azure Storage Explorer.

لقطة شاشة Azure Storage Explorer

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

تحذير

في حين أنه من المريح رؤية سجل التنفيذ في موقع تخزين الجدول، تجنب اتخاذ أي تبعية على هذا الجدول. قد يتغير مع تطور ملحق Durable Functions.

إشعار

يمكن تكوين موفري التخزين الآخرين بدلاً من موفر Azure Storage الافتراضي. اعتماداً على موفر التخزين الذي تم تكوينه لتطبيقك، قد تحتاج إلى استخدام أدوات مختلفة لفحص الحالة الأساسية. لمزيدٍ من المعلومات، راجع وثائق موفري تخزين Durable Functions.

Durable Functions Monitor

Durable Functions Monitor هي أداة رسومية لمراقبة وإدارة وتصحيح التزامن ومثيلات الكيان. وهو متوفر كملحق Visual Studio Code أو تطبيق مستقل. يمكن العثور على معلومات حول الإعداد وقائمة الميزات في Wiki هذا.

دليل استكشاف أخطاء Durable Functions وإصلاحها

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

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