Padrão de repositório de configuração externo

Configuração de Aplicativo do Azure
Armazenamento do Blobs do Azure

Mova as informações de configuração para fora do pacote de implantação de aplicativo para um local centralizado. Ele pode fornecer oportunidades para facilitar o gerenciamento e controle dos dados de configuração e para compartilhar os dados de configuração nos aplicativos e instâncias do aplicativo.

Contexto e problema

A maioria dos ambientes de runtime do aplicativo inclui informações de configuração que são mantidas nos arquivos implantados com o aplicativo. Em alguns casos, é possível editar esses arquivos para alterar o comportamento do aplicativo depois que ele é implantado. No entanto, as alterações na configuração requerem que o aplicativo seja reimplantado, geralmente resultando em tempo de inatividade inaceitável e outras sobrecargas administrativas.

Os arquivos de configuração locais também limitam a configuração a um único aplicativo, porém, às vezes, pode ser útil compartilhar as definições de configuração entre vários aplicativos. Alguns exemplos são as cadeias de conexão de banco de dados, informações de tema de interface do usuário ou as URLs de filas e o armazenamento usado por um conjunto de aplicativos relacionados.

É difícil para gerenciar as alterações de configurações locais em várias instâncias em execução do aplicativo, especialmente em um cenário hospedado na nuvem. Isso pode resultar em instâncias que usando definições de configuração diferentes, enquanto a atualização está sendo implantada.

Além disso, as atualizações para aplicativos e componentes podem exigir alterações nos esquemas de configuração. Muitos sistemas de configuração não dão suporte a versões diferentes de informações de configuração.

Solução

Armazene as informações de configuração no armazenamento externo e forneça uma interface que pode ser usada para ler e atualizar as definições de configuração de forma rápida e eficiente. O tipo de repositório externo depende do ambiente de hospedagem e do runtime do aplicativo. Em um cenário hospedado na nuvem, ele normalmente é um serviço de armazenamento baseado em nuvem ou serviço de configuração dedicado, mas pode ser um banco de dados hospedado ou outro sistema personalizado.

O repositório de backup escolhido para as informações de configuração deve ter uma interface que forneça acesso consistente e de fácil utilização. Ele deve expor as informações em um formato com tipo e estrutura corretos. A implementação também pode precisar autorizar o acesso dos usuários para proteger os dados de configuração e ser flexível o suficiente para permitir o armazenamento de várias versões de configuração (como desenvolvimento, preparo ou produção, incluindo várias versões de cada uma delas).

Muitos sistemas de configuração internos leem os dados quando o aplicativo é iniciado e os armazenar em cache na memória para fornecer acesso rápido e minimizar o impacto sobre o desempenho do aplicativo. Dependendo do tipo de repositório de backup usado e da latência dele, pode ser útil implementar um mecanismo de armazenamento em cache no repositório de configuração externo. Para saber mais, consulte Diretrizes de caching. A figura mostra uma visão geral do Padrão de repositório de configuração externo com um cache local opcional.

Uma visão geral do Padrão de repositório de configuração externo com um cache local opcional

Problemas e considerações

Considere os seguintes pontos ao decidir como implementar esse padrão:

Escolha um repositório de backup que ofereça desempenho aceitável, alta disponibilidade, robustez e que possa passar por backup como parte do processo de administração e manutenção do aplicativo. Em um aplicativo hospedado na nuvem, geralmente é uma boa opção usar um mecanismo de armazenamento ou serviço dedicado de plataforma de configuração para atender a esses requisitos.

Projete o esquema do repositório de backup para permitir flexibilidade quanto aos tipos de informações que ele pode conter. Verifique se ele fornece todos os requisitos de configuração, como dados com tipo, coleções de configurações, várias versões de configurações e outros recursos exigidos pelos aplicativos que os utilizam. Deve ser fácil estender o esquema para dar suporte a configurações adicionais à medida que os requisitos mudam.

Considere as capacidades físicas do repositório de backup, como ela se relaciona com a forma que as informações de configuração são armazenadas e os efeitos sobre o desempenho. Por exemplo, armazenar um documento XML que contém informações de configuração exigirá que a interface de configuração ou o aplicativo analise o documento para ler as configurações individuais. Será mais complicado atualizar uma configuração, porém armazená-las em cache pode ajudar a compensar o desempenho de leitura mais lento.

Considere como a interface de configuração permitirá o controle do escopo e a herança de definições de configuração. Por exemplo, isso pode ser um requisito para definições de configuração de escopo no nível da organização, do aplicativo ou do computador. Pode ser necessário dar suporte à delegação do controle de acesso a diferentes escopos e impedir ou permitir que aplicativos individuais substituam as configurações.

Verifique se a interface de configuração pode expor os dados de configuração nos formatos exigidos como valores com tipo, coleções, pares de chave/valor ou recipientes de propriedades.

Considere como a interface do repositório de configuração se comportará quando as configurações contiverem erros ou se não existirem no repositório de backup. Pode ser apropriado retornar as configurações padrão e os log de erros. Considere também aspectos como a diferenciação de maiúsculas e minúsculas nas chaves ou nomes das definições de configuração, o armazenamento e manipulação de dados binários e as maneiras como valores nulos ou vazios são manipulados.

Considere como proteger os dados de configuração para permitir o acesso somente aos usuários e aplicativos apropriados. Esse provavelmente é um recurso da interface do repositório de configuração, mas também é necessário garantir que os dados no repositório de backup não possam ser acessados diretamente sem a devida permissão. Verifique se há separação estrita entre as permissões necessárias para ler e gravar os dados de configuração. Considere também se você precisa criptografar algumas ou todas as definições de configuração e como isso será implementado na interface do repositório de configuração.

Configurações armazenadas centralmente, que alteram o comportamento do aplicativo durante o runtime, são cruciais e devem ser implantados, atualizados e gerenciados usando os mesmos mecanismos da implantação de código do aplicativo. Por exemplo, as alterações que podem afetar a mais de um aplicativo precisam ser realizadas usando um teste completo e a abordagem de implantação de teste para garantir que a alteração seja apropriada para todos os aplicativos que usam essa configuração. Se um administrador editar uma configuração para atualizar um aplicativo, ele poderia afetar negativamente outros aplicativos que usam a mesma configuração.

Se um aplicativo armazenar as informações de configuração em cache, ele precisará ser alertado se as configurações forem alteradas. Pode ser possível implementar uma política de expiração de dados de configuração armazenados em cache para que essas informações sejam atualizadas automaticamente e periodicamente, e que as alterações sejam selecionadas (e as devidas ações sejam tomadas).

Embora os dados de configuração de cache possam ajudar a resolver problemas transitórios de conectividade com o repositório de configuração externo no runtime do aplicativo, isso normalmente não resolverá o problema se o repositório externo estiver inativo quando o aplicativo for iniciado pela primeira vez. Assegure-se que o pipeline de implantação do aplicativo possa fornecer o último conjunto conhecido de valores de configuração em um arquivo de configuração como um fallback, caso o aplicativo não consiga recuperar valores dinâmicos quando ele for iniciado.

Quando usar esse padrão

Esse padrão é útil para:

  • As definições de configuração compartilhadas entre vários aplicativos e instâncias do aplicativo ou nas quais uma configuração padrão precisa ser imposta em vários aplicativos e instâncias do aplicativo.

  • Um sistema de configuração padrão que não dá suporte a todas as definições de configuração necessárias, como armazenamento de imagens ou tipos de dados complexos.

  • Como um repositório complementar para algumas das configurações de aplicativos, talvez permitindo que os aplicativos substituam algumas ou todas as configurações armazenadas centralmente.

  • Como uma maneira de simplificar a administração de vários aplicativos e, opcionalmente, para monitorar o uso de definições de configuração por meio de registro em log de todos os tipos de acesso para o repositório de configuração.

Design de carga de trabalho

Um arquiteto deve avaliar como o padrão do Repositório de Configuração Externa pode ser usado no design de sua carga de trabalho para abordar as metas e os princípios abordados nos pilares da Estrutura de Bem-Arquitetura do Azure. Por exemplo:

Pilar Como esse padrão apoia os objetivos do pilar
A Excelência Operacional ajuda a fornecer qualidade na carga de trabalho por meio de processos padronizados e coesão da equipe. Essa separação entre a configuração do aplicativo e o código do aplicativo oferece suporte à configuração específica do ambiente e aplica o controle de versão aos valores de configuração. Os armazenamentos de configuração externos também são um local comum para gerenciar sinalizadores de recursos para permitir práticas de implantação seguras.

- OE:10 Design de automação
- OE:11 Práticas de implantação segura

Tal como acontece com qualquer decisão de design, considere quaisquer compensações em relação aos objetivos dos outros pilares que possam ser introduzidos com este padrão.

Exemplo de repositório de backup personalizado

Em um aplicativo hospedado do Microsoft Azure, uma opção possível para armazenar informações de configuração externamente é usar o Armazenamento do Microsoft Azure. Ele é flexível, oferece alto desempenho e é replicado três vezes com failover automático para proporcionar alta disponibilidade. O Armazenamento de Tabelas do Azure fornece um repositório de chave/valor com a capacidade de usar um esquema flexível para os valores. O Armazenamento de Blobs do Azure fornece um repositório hierárquico e baseado em contêiner que pode conter qualquer tipo de dados em blobs nomeados individualmente.

Ao implementar esse padrão, você será responsável por abstrair o Armazenamento de Blobs do Azure e expor suas configurações em seus aplicativos, incluindo verificar se há atualizações em runtime e tratar de como responder a elas.

O exemplo a seguir mostra como um repositório de configuração simplificado pode ser concebido no Armazenamento de Blobs para armazenar e expor as informações de configuração. Uma classe BlobSettingsStore pode abstrair o Armazenamento de Blobs para armazenar informações de configuração e implementa uma interface ISettingsStore simples.

public interface ISettingsStore
{
    Task<ETag> GetVersionAsync();
    Task<Dictionary<string, string>> FindAllAsync();
}

Essa interface define os métodos para recuperar as definições de configuração mantidas no repositório de configuração e inclui um número de versão que pode ser usado para detectar se as definições de configuração foram modificadas recentemente. Uma classe BlobSettingsStore usa a propriedade ETag do blob para implementar o controle de versão. A propriedade ETag é atualizada automaticamente sempre que há uma gravação em um blob.

Por padrão, essa ilustração simples expõe todas as definições de configuração como valores de cadeia de caracteres em vez de valores com tipo.

Em seguida, uma classe ExternalConfigurationManager pode fornecer um wrapper em torno de uma instância de BlobSettingsStore. Um aplicativo pode usar essa classe para recuperar as informações de configuração. Essa classe pode usar algo como as Extensões Reativas da Microsoft para publicar eventuais alterações feitas na configuração enquanto o sistema está em execução. Ela também seria responsável por implementar o padrão Cache-Aside para que as configurações forneçam resiliência e desempenho adicionais.

O conjunto de dados pode ter aparência semelhante à mostrada a seguir.

static void Main(string[] args)
{
    // Start monitoring configuration changes.
    ExternalConfiguration.Instance.StartMonitor();

    // Get a setting.
    var setting = ExternalConfiguration.Instance.GetAppSetting("someSettingKey");
    …
}

Usando a Configuração de Aplicativos do Azure

Embora a criação de um repositório de configuração personalizado possa ser necessária em algumas situações, muitos aplicativos podem usar em vez disso a Configuração de Aplicativos do Azure. A Configuração de Aplicativos do Azure dá suporte a pares chave-valor que podem conter namespaces. As chaves são tipadas e têm controle de versão individual. A Configuração de Aplicativos do Azure também dá suporte a instantâneos de ponto no tempo de configuração para que você possa inspecionar ou até mesmo reverter facilmente para valores de configuração anteriores. Os valores de configuração podem ser exportados, de modo que uma cópia da configuração possa ser enviada com seu aplicativo caso o serviço esteja inacessível quando o aplicativo estiver iniciando.

Bibliotecas de cliente

Muitos desses recursos são expostos por meio de bibliotecas de clientes que se integram ao runtime do aplicativo para facilitar a busca e o cache de valores, atualizando valores após cada alteração e até mesmo tratando interrupções transitórias do serviço de Configuração de Aplicativos.

Runtime Biblioteca de Clientes Observações Início rápido
.NET Microsoft.Extensions.Configuration.AzureAppConfiguration Provedor para Microsoft.Extensions.Configuration Início rápido
ASP.NET Microsoft.Azure.AppConfiguration.AspNetCore Provedor para Microsoft.Extensions.Configuration Início rápido
Azure Functions no .NET Microsoft.Extensions.Configuration.AzureAppConfiguration Usado com extensões do Azure Functions para dar suporte à configuração em Startup.cs Início rápido
.NET Framework Microsoft.Configuration.ConfigurationBuilders.AzureAppConfiguration Criador de configuração para System.Configuration Início rápido
Java Spring com.azure.spring > azure-spring-cloud-appconfiguration-config Dá suporte a acesso ao Spring Framework via ConfigurationProperties Início rápido
Python azure.appconfiguration Fornece um AzureAppConfigurationClient Início rápido
JavaScript/Node.js @azure/app-configuration Fornece um AppConfigurationClient Início rápido

Além das bibliotecas de cliente, há também uma GitHub Action de Sincronização da Configuração de Aplicativos do Azure e tarefas do Azure DevOps de Pull da Configuração de Aplicativos do Azure & Push da Configuração de Aplicativos do Azure para integrar as etapas de configuração ao processo de build.

Próximas etapas