Condividi tramite


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

Il runtime di Durable Functions mantiene automaticamente i parametri di funzione, restituisce valori e altro stato all'hub attività per garantire un'esecuzione affidabile. Tuttavia, la quantità e la frequenza dei dati resi persistenti nell'archiviazione durevole possono influire sulle prestazioni dell'applicazione e sui costi delle transazioni di archiviazione. A seconda del tipo di dati archiviati dall'applicazione, potrebbe essere necessario considerare anche i criteri di conservazione e privacy dei dati.

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à.
  • I messaggi archiviano gli input o gli output della funzione, 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 di 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à.

La posizione e il modo in cui gli stati e i messaggi vengono rappresentati nell'archiviazione dipendono dal provider di archiviazione. Il provider predefinito di Durable Functions è Archiviazione di Azure, che rende persistenti i dati in code, tabelle e BLOB in un account Archiviazione di Azure specificato.

Tipi di dati serializzati e persistenti

L'elenco seguente mostra i diversi tipi di dati che verranno serializzati e salvati in modo permanente 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 orchestrazione, attività ed entità
  • Nomi di eventi esterni e payload
  • Payload dello stato di orchestrazione personalizzati
  • Messaggi di terminazione dell'orchestrazione
  • Payload timer durevoli
  • URL di richiesta e risposta HTTP durevoli, intestazioni e payload
  • Payload di chiamata e segnale 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 prima crittografare i dati usando chiavi di crittografia personalizzate in modo che i dati vengano salvati in modo permanente nel formato pre-crittografato.

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 quantità illimitate di tempo. Questo aspetto è importante quando si tratta di ruotare le chiavi di crittografia perché un'orchestrazione o entità può essere eseguita più a lungo dei criteri di rotazione delle chiavi. Se si verifica una rotazione delle chiavi, la chiave usata per crittografare i dati potrebbe non essere più disponibile per decrittografarla al successivo esecuzione dell'orchestrazione o dell'entità. La crittografia dei clienti è quindi consigliata solo quando si prevede che le orchestrazioni e le entità vengano eseguite per periodi di tempo relativamente brevi.

Personalizzazione della serializzazione e deserializzazione

Logica di serializzazione predefinita

Durable Functions per .NET in-process usa internamente Json.NET per serializzare i dati di orchestrazione ed 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 qui JsonSerializerSettings .

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 è proprietari del 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 la modalità di serializzazione dei dati e delle eccezioni. Il codice di esempio seguente illustra come usare l'inserimento delle dipendenze per eseguire l'override delle impostazioni di serializzazione predefinite Json.NET usando implementazioni personalizzate delle interfacce del IMessageSerializerSettingsFactory 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
            }
        }
    }
}