Persistenza e serializzazione dei dati in Durable Functions (Funzioni di Azure)

Il runtime di Durable Functions mantiene automaticamente i parametri di funzione, i valori restituiti e altri stati nell'hub attività per fornire un'esecuzione affidabile. Tuttavia, la quantità e la frequenza dei dati persistenti nell'archiviazione durevole possono influire sulle prestazioni delle applicazioni e sui costi delle transazioni di archiviazione. A seconda del tipo di dati archiviati dall'applicazione, i criteri di conservazione dei dati e privacy possono essere considerati anche.

Contenuto dell'hub attività

Hub attività archivia lo stato corrente delle istanze e tutti i messaggi in sospeso:

  • Gli stati dell'istanza archiviano lo stato corrente e la cronologia di un'istanza. Per le istanze di orchestrazione, questo stato include lo stato di runtime, la cronologia dell'orchestrazione, gli input, gli output e lo stato personalizzato. Per le istanze di entità, include lo stato dell'entità.
  • Messaggi archivia gli input o gli output delle funzioni, i payload degli eventi e i metadati usati per scopi interni, ad esempio il routing e la correlazione end-to-end.

I messaggi vengono eliminati dopo l'elaborazione, ma gli stati dell'istanza vengono mantenuti a meno che non vengano eliminati in modo esplicito dall'applicazione o da un operatore. In particolare, una cronologia dell'orchestrazione rimane in archiviazione anche dopo il completamento dell'orchestrazione.

Per un esempio di come gli stati e i messaggi rappresentano lo stato di avanzamento di un'orchestrazione, vedere l'esempio di esecuzione dell'hub attività.

Dove e come vengono rappresentati gli stati e i messaggi nell'archiviazione dipendono dal provider di archiviazione. Durable Functions provider predefinito è Archiviazione di Azure, che mantiene i dati nelle code, nelle tabelle e nei BLOB in un account di archiviazione di Azure specificato.

Tipi di dati serializzati e persistenti

L'elenco seguente mostra i diversi tipi di dati che verranno serializzati e persistenti quando si usano le funzionalità di Durable Functions:

  • Tutti gli input e gli output dell'agente di orchestrazione, dell'attività e delle funzioni di entità, inclusi gli ID e le eccezioni non gestite
  • Nomi di funzioni di orchestrazione, attività e entità
  • Nomi di eventi esterni e payload
  • Payload di stato dell'orchestrazione personalizzati
  • Messaggi di terminazione dell'orchestrazione
  • Payload timer durevoli
  • URL di richiesta e risposta HTTP durevoli, intestazioni e payload
  • Payload di chiamate e segnali di entità
  • Payload dello stato dell'entità

Uso dei dati sensibili

Quando si usa il provider di archiviazione di Azure, tutti i dati vengono crittografati automaticamente inattivi. Tuttavia, chiunque abbia accesso all'account di archiviazione può leggere i dati nel formato non crittografato. Se è necessaria una protezione più avanzata per i dati sensibili, è consigliabile crittografare prima i dati usando le proprie chiavi di crittografia in modo che i dati vengano mantenuti nel formato precrittografato.

In alternativa, gli utenti .NET hanno la possibilità di implementare provider di serializzazione personalizzati che forniscono la crittografia automatica. Un esempio di serializzazione personalizzata con crittografia è disponibile in questo esempio di GitHub.

Nota

Se si decide di implementare la crittografia a livello di applicazione, tenere presente che le orchestrazioni e le entità possono esistere per un periodo di tempo indefinito. Ciò è importante quando si tratta di ruotare le chiavi di crittografia perché un'orchestrazione o entità può essere eseguita più lunga dei criteri di rotazione delle chiavi. Se si verifica una rotazione delle chiavi, la chiave utilizzata per crittografare i dati potrebbe non essere più disponibile per decrittografarla alla successiva esecuzione dell'orchestrazione o dell'entità. La crittografia dei clienti è pertanto consigliata solo quando le orchestrazioni e le entità devono essere eseguite per periodi relativamente brevi di tempo.

Personalizzazione della serializzazione e deserializzazione

Logica di serializzazione predefinita

Durable Functions per .NET in-process usa internamente Json.NET per serializzare i dati dell'orchestrazione e dell'entità in JSON. Le impostazioni di Json.NET predefinite usate sono:

Input, output e stato:

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

Eccezioni:

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

Leggere la documentazione più dettagliata quiJsonSerializerSettings.

Personalizzazione della serializzazione con attributi .NET

Durante la serializzazione, Json.NET cerca vari attributi su classi e proprietà che controllano il modo in cui i dati vengono serializzati e deserializzati da JSON. Se si possiede il codice sorgente per il tipo di dati passato alle API Durable Functions, è consigliabile aggiungere questi attributi al tipo per personalizzare la serializzazione e la deserializzazione.

Personalizzazione della serializzazione con inserimento delle dipendenze

Le app per le funzioni destinate a .NET ed eseguite nel runtime di Funzioni V3 possono usare l'inserimento delle dipendenze (DI) per personalizzare il modo in cui vengono serializzati i dati e le eccezioni. Il codice di esempio seguente illustra come usare DI per eseguire l'override delle impostazioni di serializzazione predefinite Json.NET usando implementazioni personalizzate delle IMessageSerializerSettingsFactory interfacce del servizio e IErrorSerializerSettingsFactory .

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