Trvalost dat a serializace v Durable Functions (Azure Functions)

Modul runtime Durable Functions automaticky zachovává parametry funkce, vrací hodnoty a další stav do centra úloh, aby se zajistilo spolehlivé provádění. Množství a frekvence dat uchováných v trvalém úložišti však můžou mít vliv na výkon aplikace a náklady na transakce úložiště. V závislosti na typu dat, která vaše aplikace ukládá, může být také potřeba zvážit uchovávání dat a zásady ochrany osobních údajů.

Obsah centra úloh

Centra úloh ukládají aktuální stav instancí a všechny čekající zprávy:

  • Stavy instancí ukládají aktuální stav a historii instance. U instancí orchestrace tento stav zahrnuje stav modulu runtime, historii orchestrace, vstupy, výstupy a vlastní stav. U instancí entit zahrnuje stav entity.
  • Zprávy ukládají vstupy nebo výstupy funkcí, datové části událostí a metadata, která se používají pro interní účely, jako je směrování a kompletní korelace.

Zprávy se po zpracování odstraní, ale stavy instancí se zachovají, pokud je aplikace nebo operátor explicitně nesmaže. Historie orchestrace zůstává v úložišti i po dokončení orchestrace.

Příklad toho, jak stavy a zprávy reprezentují průběh orchestrace, najdete v příkladu spuštění centra úloh.

Umístění a způsob znázornění stavů a zpráv v úložišti závisí na poskytovateli úložiště. výchozím zprostředkovatelem Durable Functions je Azure Storage, která udržuje data ve frontách, tabulkách a objektech blob v účtu služby Azure Storage, který zadáte.

Typy dat, která se serializují a uchovávají

Následující seznam ukazuje různé typy dat, které budou serializovány a zachovány při použití funkcí Durable Functions:

  • Všechny vstupy a výstupy funkcí orchestrátoru, aktivit a entit, včetně všech ID a neošetřených výjimek
  • Názvy orchestrátoru, aktivit a funkcí entit
  • Názvy a datové části externích událostí
  • Vlastní datové části stavu orchestrace
  • Zprávy o ukončení orchestrace
  • Odolné datové části časovače
  • Odolné adresy URL požadavků a odpovědí HTTP, hlavičky a datové části
  • Datové části volání a signálu entit
  • Datové části stavu entit

Práce s citlivými daty

Při použití poskytovatele služby Azure Storage se všechna neaktivní uložená data automaticky šifrují. Každý, kdo má přístup k účtu úložiště, ale může číst data v nezašifrované podobě. Pokud potřebujete silnější ochranu citlivých dat, zvažte napřed šifrování dat pomocí vlastních šifrovacích klíčů, aby se data zachovala v předšifrované podobě.

Alternativně uživatelé .NET mají možnost implementovat vlastní zprostředkovatele serializace, kteří poskytují automatické šifrování. Příklad vlastní serializace s šifrováním najdete v této ukázce Na GitHubu.

Poznámka

Pokud se rozhodnete implementovat šifrování na úrovni aplikace, mějte na paměti, že orchestrace a entity můžou existovat po neomezenou dobu. Záleží na tom, kdy je čas šifrovací klíče obměňovat, protože orchestrace nebo entity můžou běžet déle než vaše zásady obměně klíčů. Pokud dojde k obměně klíčů, klíč použitý k šifrování dat už nemusí být při příštím spuštění orchestrace nebo entity dostupný k jejich dešifrování. Šifrování zákazníka se proto doporučuje pouze v případě, že se očekává, že orchestrace a entity poběží relativně krátkou dobu.

Přizpůsobení serializace a deserializace

Výchozí logika serializace

Durable Functions pro .NET interně používá Json.NET k serializaci orchestrace a dat entit do formátu JSON. Používají se výchozí nastavení Json.NET:

Vstupy, výstupy a stav:

JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.None,
    DateParseHandling = DateParseHandling.None,
}

Výjimky:

JsonSerializerSettings
{
    ContractResolver = new ExceptionResolver(),
    TypeNameHandling = TypeNameHandling.Objects,
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
}

Podrobnější dokumentaci si můžete přečístJsonSerializerSettings tady.

Přizpůsobení serializace pomocí atributů .NET

Během serializace Json.NET hledá různé atributy tříd a vlastností, které řídí způsob serializace a deserializace dat z JSON. Pokud vlastníte zdrojový kód pro datový typ předaný rozhraním API Durable Functions, zvažte přidání těchto atributů do typu pro přizpůsobení serializace a deserializace.

Přizpůsobení serializace pomocí injektáže závislostí

Aplikace funkcí, které cílí na .NET a běží na modulu runtime Functions v3, můžou pomocí injektáže závislostí (DI) přizpůsobit způsob serializace dat a výjimek. Následující vzorový kód ukazuje, jak pomocí DI přepsat výchozí nastavení serializace Json.NET pomocí vlastních implementací IMessageSerializerSettingsFactory rozhraní a IErrorSerializerSettingsFactory služby.

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System.Collections.Generic;

[assembly: FunctionsStartup(typeof(MyApplication.Startup))]
namespace MyApplication
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddSingleton<IMessageSerializerSettingsFactory, CustomMessageSerializerSettingsFactory>();
            builder.Services.AddSingleton<IErrorSerializerSettingsFactory, CustomErrorSerializerSettingsFactory>();
        }

        /// <summary>
        /// A factory that provides the serialization for all inputs and outputs for activities and
        /// orchestrations, as well as entity state.
        /// </summary>
        internal class CustomMessageSerializerSettingsFactory : IMessageSerializerSettingsFactory
        {
            public JsonSerializerSettings CreateJsonSerializerSettings()
            {
                // Return your custom JsonSerializerSettings here
            }
        }

        /// <summary>
        /// A factory that provides the serialization for all exceptions thrown by activities
        /// and orchestrations
        /// </summary>
        internal class CustomErrorSerializerSettingsFactory : IErrorSerializerSettingsFactory
        {
            public JsonSerializerSettings CreateJsonSerializerSettings()
            {
                // Return your custom JsonSerializerSettings here
            }
        }
    }
}