Persistência de dados e serialização em Durable Functions (Funções do Azure)

O Durable Functions runtime persiste automaticamente os parâmetros de função, os valores devolvidos e outro estado ao hub de tarefas para fornecer uma execução fiável. No entanto, a quantidade e a frequência dos dados mantidos no armazenamento durável podem afetar o desempenho da aplicação e os custos de transação de armazenamento. Consoante o tipo de dados que a sua aplicação armazena, as políticas de retenção de dados e privacidade também podem ter de ser consideradas.

Conteúdo do Hub de Tarefas

Os hubs de tarefas armazenam o estado atual das instâncias e quaisquer mensagens pendentes:

  • Os estados de instância armazenam o estado e o histórico atuais de uma instância. Para instâncias de orquestração, este estado inclui o estado do runtime, o histórico de orquestração, entradas, saídas e estado personalizado. Para instâncias de entidade, inclui o estado da entidade.
  • As mensagens armazenam entradas ou saídas de funções, payloads de eventos e metadados utilizados para fins internos, como encaminhamento e correlação ponto a ponto.

As mensagens são eliminadas após serem processadas, mas os estados da instância persistem, a menos que sejam explicitamente eliminadas pela aplicação ou por um operador. Em particular, uma história de orquestração permanece no armazenamento mesmo após a conclusão da orquestração.

Para obter um exemplo de como os estados e as mensagens representam o progresso de uma orquestração, veja o exemplo de execução do hub de tarefas.

Onde e como os estados e mensagens são representados no armazenamento depende do fornecedor de armazenamento. O fornecedor predefinido do Durable Functions é o Armazenamento do Azure, que mantém os dados em filas, tabelas e blobs numa conta de Armazenamento do Azure que especificar.

Tipos de dados serializados e persistentes

A lista seguinte mostra os diferentes tipos de dados que serão serializados e mantidos ao utilizar funcionalidades de Durable Functions:

  • Todas as entradas e saídas de funções de orquestrador, atividade e entidade, incluindo IDs e exceções não processadas
  • Nomes de funções de orquestrador, atividade e entidade
  • Nomes e payloads de eventos externos
  • Payloads de estado de orquestração personalizados
  • Mensagens de terminação de orquestração
  • Payloads de temporizador durável
  • URLs, cabeçalhos e payloads de pedidos, respostas e pedidos HTTP duráveis
  • Payloads de chamadas de entidades e sinais
  • Payloads do estado da entidade

Trabalhar com dados confidenciais

Ao utilizar o fornecedor de Armazenamento do Azure, todos os dados são encriptados automaticamente inativos. No entanto, qualquer pessoa com acesso à conta de armazenamento pode ler os dados no seu formulário não encriptado. Se precisar de uma proteção mais forte para dados confidenciais, considere primeiro encriptar os dados com as suas próprias chaves de encriptação para que os dados sejam mantidos no seu formulário pré-encriptado.

Em alternativa, os utilizadores do .NET têm a opção de implementar fornecedores de serialização personalizados que fornecem encriptação automática. Pode encontrar um exemplo de serialização personalizada com encriptação neste exemplo do GitHub.

Nota

Se decidir implementar a encriptação ao nível da aplicação, tenha em atenção que as orquestrações e as entidades podem existir por tempo indeterminado. Isto importa quando chega a altura de rodar as chaves de encriptação porque uma orquestração ou entidades podem ser executadas por mais tempo do que a sua política de rotação de chaves. Se ocorrer uma rotação de chaves, a chave utilizada para encriptar os seus dados poderá deixar de estar disponível para os desencriptar da próxima vez que a orquestração ou a entidade forem executadas. Por conseguinte, a encriptação do cliente só é recomendada quando se espera que as orquestrações e as entidades sejam executadas durante períodos de tempo relativamente curtos.

Personalizar a serialização e a desserialização

Lógica de serialização predefinida

Durable Functions para .NET no processo interno utiliza Json.NET para serializar dados de orquestração e entidade para JSON. As predefinições Json.NET utilizadas são:

Entradas, Saídas e Estado:

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

Exceções:

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

Leia mais detalhadamente a documentação aquiJsonSerializerSettings.

Personalizar a serialização com atributos .NET

Durante a serialização, Json.NET procura vários atributos em classes e propriedades que controlam a forma como os dados são serializados e desselizados a partir de JSON. Se for o proprietário do código fonte do tipo de dados transmitido às APIs Durable Functions, considere adicionar estes atributos ao tipo para personalizar a serialização e a desserialização.

Personalizar a serialização com a Injeção de Dependências

As aplicações de funções que visam .NET e são executadas no runtime das Funções V3 podem utilizar a Injeção de Dependência (DI) para personalizar a forma como os dados e as exceções são serializados. O seguinte código de exemplo demonstra como utilizar o DI para substituir as predefinições de serialização Json.NET com implementações personalizadas das IMessageSerializerSettingsFactory interfaces de serviço 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
            }
        }
    }
}