Compartilhar via


Persistência de dados e serialização na Durable Functions (Azure Functions)

O tempo de execução do Durable Functions persiste automaticamente os parâmetros da função, os valores de retorno e outros estados para o hub de tarefas para fornecer uma execução confiável. No entanto, a quantidade e a frequência dos dados persistidos para o armazenamento durável podem afetar o desempenho do aplicativo e os custos de transação de armazenamento. Dependendo do tipo de dados que seu aplicativo armazena, a retenção de dados e as políticas de privacidade também podem precisar ser consideradas.

Conteúdo do Hub de Tarefas

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

  • Os estados da instância armazenam o status atual e o histórico de uma instância. Para instâncias de orquestração, esse estado inclui o estado de runtime, o histórico de orquestração, as entradas, as saídas e o status personalizado. Para instâncias de entidade, inclui o estado da entidade.
  • As mensagens armazenam as entradas ou as saídas da função, as cargas dos eventos e os metadados que são usados para fins internos, como roteamento e correlação de ponta a ponta.

As mensagens serão excluídas após processadas, mas os estados de instância persistirão, a menos que sejam excluídos explicitamente pelo aplicativo ou por um operador. Em particular, um histórico de orquestração permanece armazenado 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, consulte o exemplo de execução do hub de tarefas.

Onde e como os estados e as mensagens serão representados no armazenamento dependem do provedor de armazenamento. O provedor padrão das Durable Functions usa o Armazenamento do Azure que persiste os dados em filas, tabelas e blobs em uma conta do Armazenamento do Azure especificada por você.

Tipos de dados que são serializados e persistentes

A seguinte lista mostra os diferentes tipos de dados que serão serializados e persistidos quando os recursos das Durable Functions forem usados:

  • Todas as entradas e saídas de orquestrador, atividade e funções de entidade, incluindo quaisquer IDs e exceções sem tratamento
  • Nomes de funções do Orchestrator, da atividade e da entidade
  • Nomes e cargas de eventos externos
  • Conteúdos de status de orquestração personalizados
  • Mensagens de encerramento de orquestração
  • Conteúdos de temporizador duráveis
  • URLs de solicitação e resposta de HTTP duráveis, cabeçalhos e conteúdos
  • Conteúdos de chamada de entidade e de sinal
  • Conteúdos de estado de entidade

Trabalhando com dados confidenciais

Quando o provedor do Armazenamento do Azure é usado, todos os dados são criptografados automaticamente em repouso. No entanto, qualquer pessoa com acesso à conta de armazenamento pode ler os dados em sua forma descriptografada. Caso você precise obter uma proteção mais forte para os dados confidenciais, considere, primeiro, a criptografia dos dados usando suas chaves de criptografia para que os dados sejam persistidos no respectivo formato previamente criptografado.

Como alternativa, os usuários do .NET têm a opção de implementar provedores de serialização personalizados que fornecem criptografia automática. Um exemplo de serialização personalizada com criptografia pode ser encontrado neste exemplo do GitHub.

Observação

Se você decidir implementar a criptografia no nível do aplicativo, lembre-se de que as orquestrações e entidades podem existir por períodos indefinidos de tempo. Isso é importante quando se trata de girar suas chaves de criptografia porque uma orquestração ou entidades podem ser executadas por mais tempo do que a política de rotação de chaves. Se ocorrer uma rotação de chaves, a chave usada para criptografar seus dados poderá não estar mais disponível para descriptografá-la na próxima vez que sua orquestração ou entidade for executada. A criptografia do cliente é, portanto, recomendada somente quando as orquestrações e entidades são esperadas para serem executadas por períodos de tempo relativamente curtos.

Personalizando a serialização e desserialização

Lógica de serialização padrão

O Durable Functions para .NET em processo usa internamente o Json.NET para serializar dados de orquestração e entidade para JSON. As configurações padrão do Json.NET usadas 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,
}

Ler a documentação mais detalhada sobre JsonSerializerSettingsaqui.

Personalizando a serialização com atributos .NET

Durante a serialização, o Json.NET procura vários atributos em classes e propriedades que controlam como os dados são serializados e desserializados no JSON. Se você possui o código-fonte para o tipo de dados passados para as APIs da Durable Functions, considere adicionar esses atributos ao tipo para personalizar a serialização e desserialização.

Personalizando a serialização com Injeção de Dependência

Os aplicativos de funções direcionados ao .NET e executados no tempo de execução do Functions V3 podem usar Injeção de Dependência (DI) para personalizar como os dados e as exceções são serializados. O código de exemplo a seguir demonstra como usar a DI para substituir as configurações padrão de serialização do Json.NET usando implementações personalizadas das interfaces de serviço IMessageSerializerSettingsFactory 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
            }
        }
    }
}