مشاركة عبر


أفضل الممارسات لعمليات توزيع أجهزة إنترنت الأشياء على نطاق واسع

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

توفير أجهزة جديدة

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

استخدام جدول توفير متدرج

لنشر الأجهزة بحجم الملايين، قد يؤدي تسجيل جميع الأجهزة في وقت واحد إلى إغراق مثيل DPS بسبب التقييد (رمز 429, Too Many Requestsاستجابة HTTP) والفشل في تسجيل أجهزتك. لمنع مثل هذا التقييد، استخدم جدول تسجيل مرحلي للأجهزة. قم بتكوين أحجام دفعات تسجيل الجهاز وفقا لحصص وحدود DPS. على سبيل المثال، إذا كان معدل التسجيل 200 جهاز في الدقيقة، فسيكون حجم الدفعة للإلحاق 200 جهاز لكل دفعة.

عمليات إعادة المحاولة

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

بدلا من إعادة محاولة التوزيع على الفور عند تقييده، انتظر حتى الوقت المحدد في retry-after العنوان. إذا لم يكن هناك عنوان إعادة محاولة متوفر من الخدمة، يمكن أن تساعد هذه الخوارزمية في تحقيق تجربة إلحاق جهاز أكثر سلاسة:

min_retry_delay_msec = 1000
max_retry_delay_msec = (1.0 / <load>) * <T> * 1000
max_random_jitter_msec = max_retry_delay_msec

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

  • <load> هو عامل قابل للتكوين بقيم > 0 ، مما يشير إلى أن الحمل يعمل بمتوسط وقت التحميل مضروبا في عدد الاتصالات في الثانية
  • <T> هو الحد الأدنى المطلق للوقت للتمهيد البارد للأجهزة (يتم حسابه حيث T = N / cpsN يكون العدد الإجمالي للأجهزة وهو cps حد الخدمة لعدد الاتصالات في الثانية).

لمزيد من المعلومات حول توقيت عمليات إعادة المحاولة، راجع توقيت إعادة المحاولة.

إعادة توفير الأجهزة

إعادة التوفير هي العملية التي يحتاج فيها الجهاز إلى توفير مركز IoT بعد توصيله بنجاح مسبقا. يمكن أن يكون هناك العديد من الأسباب التي تؤدي إلى الحاجة إلى إعادة اتصال جهاز بمركز إنترنت الأشياء، مثل:

  • يمكن إعادة تشغيل الجهاز بسبب انقطاع التيار الكهربائي أو فقدان الاتصال بالشبكة أو النقل الجغرافي أو تحديثات البرامج الثابتة أو إعادة تعيين المصنع أو تدوير مفتاح الشهادة.
  • قد يكون مثيل IoT Hub غير متوفر بسبب انقطاع IoT Hub غير المخطط له.

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

الأجهزة التي يمكنها تخزين سلسلة الاتصال

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

  • مركز IoT للاتصال عند إعادة تمهيد الجهاز هو نفسه مركز IoT المتصل مسبقا.

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

  • يختلف مركز IoT للاتصال عند إعادة تمهيد الجهاز عن مركز IoT المتصل مسبقا.

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

الأجهزة التي لا يمكنها تخزين سلسلة الاتصال

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

عينة إعادة التزويد

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

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace ProvisioningCache
{
  public class ProvisioningDetailsFileStorage : IProvisioningDetailCache
  {
    private string dataDirectory = null;

    public ProvisioningDetailsFileStorage()
    {
      dataDirectory = Environment.GetEnvironmentVariable("ProvisioningDetailsDataDirectory");
    }

    public ProvisioningResponse GetProvisioningDetailResponseFromCache(string registrationId)
    {
      try
        {
          var provisioningResponseFile = File.ReadAllText(Path.Combine(dataDirectory, registrationId));

          ProvisioningResponse response = JsonConvert.DeserializeObject<ProvisioningResponse>(provisioningResponseFile);

          return response;
        }
      catch (Exception ex)
      {
        return null;
      }
    }

    public void SetProvisioningDetailResponse(string registrationId, ProvisioningResponse provisioningDetails)
    {
      var provisioningDetailsJson = JsonConvert.SerializeObject(provisioningDetails);

      File.WriteAllText(Path.Combine(dataDirectory, registrationId), provisioningDetailsJson);
    }
  }
}

يمكنك استخدام تعليمات برمجية مشابهة للآتي لتحديد كيفية متابعة إعادة توصيل جهاز بعد تحديد ما إذا كانت هناك معلومات اتصال في ذاكرة التخزين المؤقت:

IProvisioningDetailCache provisioningDetailCache = new ProvisioningDetailsFileStorage();

var provisioningDetails = provisioningDetailCache.GetProvisioningDetailResponseFromCache(registrationId);

// If no info is available in cache, go through DPS for provisioning
if(provisioningDetails == null)
{
  logger.LogInformation($"Initializing the device provisioning client...");
  using var transport = new ProvisioningTransportHandlerAmqp();
  ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(dpsEndpoint, dpsScopeId, security, transport);
  logger.LogInformation($"Initialized for registration Id {security.GetRegistrationID()}.");
  logger.LogInformation("Registering with the device provisioning service... ");

  // This method will attempt to retry in case of a transient fault
  DeviceRegistrationResult result = await registerDevice(provClient);
  provisioningDetails = new ProvisioningResponse() { iotHubHostName = result.AssignedHub, deviceId = result.DeviceId };
  provisioningDetailCache.SetProvisioningDetailResponse(registrationId, provisioningDetails);
}

// If there was IoT Hub info from previous provisioning in the cache, try connecting to the IoT hub directly
// If trying to connect to the IoT hub returns status 429, make sure to retry operation honoring
//   the retry-after header
// If trying to connect to the IoT hub returns a 500-series server error, have an exponential backoff with
//   at least 5 seconds of wait-time
// For all response codes 429 and 5xx, reprovision through DPS
// Ideally, you should also support a method to manually trigger provisioning on demand
if (provisioningDetails != null)
{
  logger.LogInformation($"Device {provisioningDetails.deviceId} registered to {provisioningDetails.iotHubHostName}.");
  logger.LogInformation("Creating TPM authentication for IoT Hub...");
  IAuthenticationMethod auth = new DeviceAuthenticationWithTpm(provisioningDetails.deviceId, security);
  logger.LogInformation($"Testing the provisioned device with IoT Hub...");
  DeviceClient iotClient = DeviceClient.Create(provisioningDetails.iotHubHostName, auth, TransportType.Amqp);
  logger.LogInformation($"Registering the Method Call back for Reprovisioning...");
  await iotClient.SetMethodHandlerAsync("Reprovision",reprovisionDirectMethodCallback, iotClient);

  // Now you should start a thread into this method and do your business while the DeviceClient is still connected
  await startBackgroundWork(iotClient);
  logger.LogInformation("Wait until closed...");

  // Wait until the app unloads or is cancelled
  var cts = new CancellationTokenSource();
  AssemblyLoadContext.Default.Unloading += (ctx) => cts.Cancel();
  Console.CancelKeyPress += (sender, cpe) => cts.Cancel();

  await WhenCancelled(cts.Token);
  await iotClient.CloseAsync();
  Console.WriteLine("Finished.");
}

اعتبارات اتصال IoT Hub

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

عند اتصال الأجهزة ب IoT Hub عبر DPS، يجب عليها استخدام المنطق التالي استجابة لرموز الخطأ عند الاتصال:

  • عند تلقي أي من استجابات أخطاء الخادم المكونة من 500 سلسلة، أعد محاولة الاتصال باستخدام بيانات الاعتماد المخزنة مؤقتا أو نتائج استدعاء واجهة برمجة تطبيقات البحث عن حالة تسجيل الجهاز.
  • عند الاستلام 401, Unauthorized أو 403, Forbidden404, Not Found، قم بإجراء إعادة تسجيل كاملة عن طريق استدعاء واجهة برمجة تطبيقات تسجيل DPS.

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

إذا تم قطع اتصال الأجهزة بمركز إنترنت الأشياء، فيجب أن تحاول الأجهزة إعادة الاتصال مباشرة بنفس مركز إنترنت الأشياء لمدة 15-30 دقيقة قبل محاولة العودة إلى DPS.

سيناريوهات مركز IoT الأخرى عند استخدام DPS:

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

مراقبة الأجهزة

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

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

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