Osvědčené postupy pro nasazení zařízení IoT ve velkém měřítku

Škálování řešení IoT na miliony zařízení může být náročné. Rozsáhlá řešení je často potřeba navrhnout v souladu s limity služeb a předplatných. Když zákazníci používají službu Azure IoT Device Provisioning, používají ji v kombinaci s dalšími službami a komponentami platformy Azure IoT, jako jsou IoT Hub a sady SDK pro zařízení Azure IoT. Tento článek popisuje osvědčené postupy, vzory a vzorový kód, které můžete začlenit do návrhu, abyste využili výhod těchto služeb a umožnili nasazení škálovat na více instancí. Díky těmto vzorům a postupům, které začínají fází návrhu projektu, můžete maximalizovat výkon zařízení IoT.

Zřízení nových zařízení

Poprvé uvedení do provozu je proces prvotního připojení zařízení jako součást řešení IoT. Při práci s nasazeními ve velkém měřítku je důležité naplánovat proces zřizování, aby se zabránilo přetíženým situacím způsobeným všemi zařízeními, která se pokouší připojit najednou.

Použijte rozložený plán zřizování

V případě nasazení zařízení v rozsahu milionů může registrace všech zařízení najednou způsobit zahlcení instance DPS kvůli omezování (kód odpovědi HTTP 429, Too Many Requests) a selhání registrace vašich zařízení. Pokud chcete těmto omezením zabránit, použijte pro zařízení rozložený plán registrace. Nakonfigurujte velikosti dávek registrace zařízení v souladu s kvótami a limity DPS. Pokud je například registrační sazba 200 zařízení za minutu, velikost dávky pro začleňování je 200 zařízení na dávku.

Opakování operací

Pokud dojde k přechodným chybám kvůli zaneprázdněné službě, logika opakování umožňuje zařízením úspěšně se připojit ke cloudu IoT. Velký počet opakovaných pokusů ale může dále zhoršit výkon zaneprázdněné služby, která běží na nebo blízko své maximální kapacity. Stejně jako u jakékoli služby Azure byste měli implementovat inteligentní mechanismus opakování s exponenciálním čekáním. Další informace o různých vzorech opakování najdete v vzoru návrhu opakování a zpracování přechodných chyb.

Místo okamžitého opakování nasazení při omezování počkejte na dobu uvedenou v retry-after hlavičce. Pokud ve službě není k dispozici žádná hlavička opakování, může tento algoritmus pomoct dosáhnout plynulejšího prostředí při onboardingu zařízení:

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

S touto logikou zařízení náhodně zpožďují opětovné připojení po určitou dobu mezi min_retry_delay_msec a max_retry_delay_msec. Maximální zpoždění opakování se vypočítá s následujícími proměnnými:

  • <load> je konfigurovatelný faktor s hodnotami většími nebo rovnými > 0, což označuje, že zatížení je vykonáváno v průměrné době zatížení vynásobené počtem připojení za sekundu.
  • <T> je absolutní minimální doba pro studené spouštění zařízení (vypočítaná jako T = N / cpsN celkový počet zařízení a cps jedná se o limit služby pro počet připojení za sekundu).

Další informace o načasování operací opakování najdete v tématu Časování opakování.

Opětovné připojení vs. opětovná konfigurace zařízení

Opětovné připojení je proces, kdy se zařízení musí po úspěšném připojení přes DPS znovu připojit k centru IoT a z nějakého důvodu se odpojilo. Opětovné zřízení je proces, kdy je potřeba zřídit zařízení pro nové centrum IoT. Zařízení je třeba znovu vytvořit, protože se přesune do centra v jiné oblasti, přesune se z vývoje do testovacího centra nebo se musí znovu inicializovat v dříve přiděleném centru.

V důsledku toho může být potřeba zařízení znovu připojit k centru IoT, například:

  • Zařízení se restartuje kvůli výpadku napájení, ztrátě připojení k síti, geografické přemístění, aktualizací firmwaru, obnovení továrního nastavení nebo obměně klíčů certifikátů.
  • Instance IoT Hubu je dočasně nedostupná kvůli neplánovanému výpadku služby IoT Hub.

Při každém restartování zařízení byste znovu neměli procházet procesem zřizování. Většina zařízení, která jsou znovu zřízených, skončí připojená ke stejnému centru IoT. Místo toho by se zařízení mělo pokusit připojit ke svému centru IoT přímo pomocí informací uložených v mezipaměti z předchozího úspěšného připojení.

Při zvažování opětovného zřízení zařízení přiřaďte zařízení k jinému centru IoT pomocí vlastních zásad přidělování.

Zařízení, která můžou ukládat připojovací řetězec

Zařízení, která mají možnost ukládat svůj připojovací řetězec po počátečním zřizování, by měla tak učinit a pokusit se po restartování znovu připojit přímo ke službě IoT Hub. Tento model snižuje latenci úspěšného připojení k příslušnému centru IoT. Existují dva možné případy:

  • Centrum IoT, které se připojí při restartování zařízení, je stejné jako dříve připojené centrum IoT.

    Připojovací řetězec načtený z mezipaměti by měl fungovat správně a zařízení se může znovu připojit ke stejnému koncovému bodu. Není třeba začínat znovu s procesem zřizování.

  • Centrum IoT, které se má připojit při restartování zařízení, se liší od dříve připojeného centra IoT.

    Připojovací řetězec uložený v paměti je nepřesný. Pokus o připojení ke stejnému koncovému bodu se nezdaří, a proto se aktivuje mechanismus opakování připojení centra IoT. Jakmile je dosaženo prahové hodnoty selhání připojení IoT hubu, mechanismus opakování automaticky spustí nový začátek procesu zřizování.

Zařízení, která nemůžou ukládat připojovací řetězec

Některá zařízení nemají dostatek prostoru ani paměti pro ukládání do mezipaměti připojovacího řetězce z předchozího úspěšného připojení IoT Hubu. Po restartování se tato zařízení musí znovu zprovoznit prostřednictvím DPS. K opětovné registraci použijte rozhraní API pro registraci DPS. Mějte na paměti, že počet opětovných registrací za minutu je omezený na základě limitu registrace zařízení DPS.

Ukázka reprovizování

Příklady kódu v této části ukazují třídu pro čtení a zápis z mezipaměti zařízení, následovaný kódem, který se pokusí znovu připojit zařízení k IoT Hubu, pokud se najde připojovací řetězec a znovu vytvoří prostřednictvím DPS, pokud není.

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);
    }
  }
}

Kód podobný následujícímu byste mohli použít k určení postupu při opětovném připojení zařízení po určení, jestli jsou v mezipaměti informace o připojení:

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.");
}

Důležité informace o připojení ke službě IoT Hub

Jakékoli jedno centrum IoT je omezené na 1 milion zařízení a moduly. Pokud plánujete mít více než milion zařízení, omezte počet zařízení na 1 milion na centrum a podle potřeby přidejte rozbočovače při zvyšování rozsahu nasazení. Další informace najdete v tématu Kvóty a omezování služby IoT Hub. Pokud máte plány na více než milion zařízení a potřebujete je podporovat v konkrétní oblasti (například v oblasti EU pro požadavky na rezidenci dat), můžete nás kontaktovat a ujistit se, že oblast, do které nasazujete, má kapacitu pro podporu vašeho aktuálního a budoucího škálování.

Když se zařízení připojují ke službě IoT Hub přes DPS, měly by při připojování použít následující logiku jako reakci na chybové kódy:

  • Při příjmu jakékoli z 500 řad odpovědí na chyby serveru zkuste připojení zopakovat pomocí přihlašovacích údajů uložených v mezipaměti nebo výsledků volání rozhraní API pro vyhledávání stavu registrace zařízení.
  • Při příjmu 401, Unauthorized nebo 403, Forbidden nebo 404, Not Found proveďte úplnou opětovnou registraci voláním API pro registraci DPS.

Zařízení by měla být kdykoli schopná reagovat na příkaz opětovného zřízení iniciovaného uživatelem.

Pokud se zařízení odpojí od služby IoT Hub, pokusí se po dobu 15 až 30 minut znovu připojit přímo ke stejnému IoT Hubu, předtím než se pokusí vrátit k DPS k přerozdělení do nového IoT Hubu. Pokud je v tomto scénáři IoT hub mimo provoz a není odstraněn z registrace v DPS, zařízení se pokusí znovu připojit k tomu samému hubu, který nefunguje. Tento proces vede k tomu, že zřizování se nepodaří připojit k hubu, a výsledkem je exponenciální nárůst selhání. Ujistěte se, že IoT uzly nebudou odstraněny z vašeho prostředí a jsou k dispozici.

Monitorování zařízení

Důležitou součástí celkového nasazení je monitorování celého řešení, aby se zajistilo, že systém funguje správně. Existuje několik způsobů, jak monitorovat stav služby pro rozsáhlé nasazení zařízení IoT. Následující vzory ukazují účinnost při monitorování služby:

  • Vytvořte aplikaci pro dotazování na každou skupinu registrací v instanci DPS, získejte celková zařízení zaregistrovaná v této skupině a pak agregujte čísla z různých skupin registrací. Toto číslo poskytuje přesný počet zařízení, která jsou aktuálně zaregistrovaná přes DPS, a lze ji použít k monitorování stavu služby.
  • Monitorujte registrace zařízení v určitém období. Monitorujte například registrační sazby pro instanci DPS za posledních pět dnů. Tento přístup poskytuje pouze přibližnou hodnotu a je také omezen na časové období.

Další kroky