Editar

Padrão de aplicativo Web confiável para .NET - Aplique o padrão

Azure App Service
Azure Front Door
Azure Cache for Redis
.NET

Este artigo mostra como aplicar o padrão Reliable Web App. O padrão Reliable Web App é um conjunto de princípios e técnicas de implementação que definem como você deve modificar aplicativos Web (replataforma) ao migrar para a nuvem. Ele se concentra nas atualizações mínimas de código que você precisa fazer para ter sucesso na nuvem.

Para facilitar a aplicação dessas diretrizes, há uma implementação de referência do padrão Reliable Web App que você pode implantar.

Diagrama mostrando a arquitetura da implementação de referência.Arquitetura da implementação de referência. Baixe um arquivo Visio desta arquitetura.

As orientações a seguir usam a implementação de referência como um exemplo em todo o texto. Para aplicar o padrão Reliable Web App, siga estas recomendações alinhadas aos pilares do Well-Architected Framework:

Fiabilidade

A confiabilidade garante que seu aplicativo possa atender aos compromissos que você assume com seus clientes. Para obter mais informações, consulte a lista de verificação de revisão de design para confiabilidade. O padrão Reliable Web App introduz dois padrões de design principais no nível do código para aumentar a confiabilidade: o padrão Retry e o padrão Circuit Breaker.

Usar o padrão Repetir

O padrão Retry aborda interrupções temporárias do serviço, denominadas falhas transitórias, que geralmente são resolvidas em segundos. Essas falhas geralmente resultam de limitação de serviço, distribuição de carga dinâmica e problemas de rede em ambientes de nuvem. A implementação do padrão Retry envolve o reenvio de solicitações com falha, permitindo atrasos e tentativas configuráveis antes de conceder falhas.

Os aplicativos que usam o padrão Retry devem integrar os SDKs (kits de desenvolvimento de software) cliente do Azure e mecanismos de repetição específicos do serviço para maior eficiência. Os aplicativos que não possuem esse padrão devem adotá-lo usando as seguintes orientações.

Experimente primeiro o serviço do Azure e os SDKs de cliente

A maioria dos serviços do Azure e SDKs de cliente tem um mecanismo de repetição interno. Você deve usar o mecanismo de repetição interno para serviços do Azure para agilizar a implementação.

Exemplo: A implementação de referência usa a resiliência de conexão no Entity Framework Core para aplicar o padrão Retry em solicitações ao Banco de Dados SQL do Azure (consulte o código a seguir).

services.AddDbContextPool<ConcertDataContext>(options => options.UseSqlServer(sqlDatabaseConnectionString,
    sqlServerOptionsAction: sqlOptions =>
    {
        sqlOptions.EnableRetryOnFailure(
        maxRetryCount: 5,
        maxRetryDelay: TimeSpan.FromSeconds(3),
        errorNumbersToAdd: null);
    }));

Usar a biblioteca Polly quando a biblioteca cliente não suportar novas tentativas

Talvez seja necessário fazer chamadas para uma dependência que não seja um serviço do Azure ou não ofereça suporte ao padrão Repetir nativamente. Nesse caso, você deve usar a biblioteca Polly para implementar o padrão Retry. Polly é uma biblioteca de resiliência .NET e tratamento de falhas transitórias. Com ele, você pode usar APIs fluentes para descrever o comportamento em um local central do aplicativo.

Exemplo: A implementação de referência usa Polly para configurar a injeção de dependência do ASP.NET Core. Polly impõe o padrão Retry sempre que o código constrói um objeto que chama o IConcertSearchService objeto. Na estrutura Polly, esse comportamento é conhecido como uma política. O código extrai essa política no GetRetryPolicy método, e o GetRetryPolicy método aplica o padrão Retry toda vez que o aplicativo Web front-end chama serviços de pesquisa de concertos da API da Web (consulte o código a seguir).

private void AddConcertSearchService(IServiceCollection services)
{
    var baseUri = Configuration["App:RelecloudApi:BaseUri"];
    if (string.IsNullOrWhiteSpace(baseUri))
    {
        services.AddScoped<IConcertSearchService, MockConcertSearchService>();
    }
    else
    {
        services.AddHttpClient<IConcertSearchService, RelecloudApiConcertSearchService>(httpClient =>
        {
            httpClient.BaseAddress = new Uri(baseUri);
            httpClient.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
            httpClient.DefaultRequestHeaders.Add(HeaderNames.UserAgent, "Relecloud.Web");
        })
        .AddPolicyHandler(GetRetryPolicy())
        .AddPolicyHandler(GetCircuitBreakerPolicy());
    }
}

private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
    var delay = Backoff.DecorrelatedJitterBackoffV2(TimeSpan.FromMilliseconds(500), retryCount: 3);
    return HttpPolicyExtensions
      .HandleTransientHttpError()
      .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
      .WaitAndRetryAsync(delay);
}

O manipulador de políticas para a RelecloudApiConcertSearchService instância aplica o padrão Retry em todas as solicitações à API. Ele usa a HandleTransientHttpError lógica para detetar solicitações HTTP que ele pode tentar novamente com segurança e, em seguida, tentar novamente a solicitação com base na configuração. Ele inclui alguma aleatoriedade para suavizar possíveis picos de tráfego para a API se ocorrer um erro.

Utilizar o padrão de Disjuntor Automático

O emparelhamento dos padrões de repetição e disjuntor expande a capacidade de um aplicativo de lidar com interrupções de serviço que não estão relacionadas a falhas transitórias. O padrão de disjuntor impede que um aplicativo tente acessar continuamente um serviço que não responde. O padrão de disjuntor libera o aplicativo e evita o desperdício de ciclos de CPU para que o aplicativo mantenha sua integridade de desempenho para os usuários finais.

Exemplo: A implementação de referência adiciona o padrão de disjuntor no GetCircuitBreakerPolicy método (consulte o código a seguir).

private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
{
    return HttpPolicyExtensions
        .HandleTransientHttpError()
        .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
        .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
}

No código, o manipulador de políticas para a RelecloudApiConcertSearchService instância aplica o padrão Circuit Breaker em todas as solicitações à API. Ele usa a HandleTransientHttpError lógica para detetar solicitações HTTP que pode repetir com segurança, mas limita o número de falhas agregadas durante um período de tempo especificado.

Segurança

A segurança oferece garantias contra ataques deliberados e o abuso de seus valiosos dados e sistemas. Para obter mais informações, consulte Lista de verificação de revisão de design para segurança. O padrão Reliable Web App usa identidades gerenciadas para implementar segurança centrada em identidade. Pontos de extremidade privados, firewall de aplicativo Web e acesso restrito ao aplicativo Web fornecem uma entrada segura.

Impor privilégios mínimos

Para garantir a segurança e a eficiência, conceda apenas aos usuários (identidades de usuário) e aos serviços do Azure (identidades de carga de trabalho) as permissões de que precisam.

Atribuir permissões a identidades de usuário

Avalie as necessidades do seu aplicativo para definir um conjunto de funções que abranjam todas as ações do usuário sem sobreposição. Mapeie cada usuário para a função mais apropriada. Garantir que eles tenham acesso apenas ao que é necessário para suas funções.

Atribuir permissões a identidades de carga de trabalho

Conceda apenas as permissões que são críticas para as operações, como ações CRUD em bancos de dados ou acesso a segredos. As permissões de identidade de carga de trabalho são persistentes, portanto, você não pode fornecer permissões just-in-time ou de curto prazo para identidades de carga de trabalho.

  • Prefira o controle de acesso baseado em função (RBAC). Sempre comece com o RBAC do Azure para atribuir permissões. Ele oferece controle preciso, garantindo que o acesso seja auditável e granular. Use o RBAC do Azure para conceder apenas as permissões necessárias para que o serviço execute suas funções pretendidas.

  • Complemente com os controles de acesso de nível de serviço do Azure. Se o RBAC do Azure não cobrir um cenário específico, complemente com políticas de acesso de nível de serviço do Azure.

Configurar autenticação e autorização de usuário

A autenticação e a autorização são aspetos críticos da segurança de aplicativos Web. A autenticação é o processo de verificação da identidade de um usuário. A autorização especifica as ações que um usuário tem permissão para executar dentro do aplicativo. O objetivo é implementar autenticação e autorização sem enfraquecer sua postura de segurança. Para atingir essa meta, você precisa usar os recursos da plataforma de aplicativo do Azure (Serviço de Aplicativo do Azure) e do provedor de identidade (ID do Microsoft Entra).

Configurar autenticação de usuário

Proteja seu aplicativo Web habilitando a autenticação do usuário por meio dos recursos da sua plataforma. O Serviço de Aplicativo do Azure dá suporte à autenticação com provedores de identidade, como o Microsoft Entra ID, descarregando a carga de trabalho de autenticação do seu código.

Configurar autenticação e autorização de serviço

Configure a autenticação e a autorização de serviço para que os serviços em seu ambiente tenham as permissões para executar as funções necessárias. Use identidades gerenciadas no Microsoft Entra ID para automatizar a criação e o gerenciamento de identidades de serviço, eliminando o gerenciamento manual de credenciais. Uma identidade gerenciada permite que seu aplicativo Web acesse com segurança os serviços do Azure, como o Azure Key Vault e bancos de dados. Ele também facilita integrações de pipeline de CI/CD para implantações no Serviço de Aplicativo do Azure. No entanto, em cenários como implantações híbridas ou com sistemas herdados, continue usando suas soluções de autenticação local para simplificar a migração. Faça a transição para identidades gerenciadas quando seu sistema estiver pronto para uma abordagem moderna de gerenciamento de identidades. Para obter mais informações, consulte Monitorando identidades gerenciadas.

Use DefaultAzureCredential para configurar o código

Use DefaultAzureCredential para fornecer credenciais para desenvolvimento local e identidades gerenciadas na nuvem. DefaultAzureCredential gera uma aquisição de TokenCredential token OAuth. Ele lida com a maioria dos cenários do SDK do Azure e bibliotecas de cliente da Microsoft. Ele deteta o ambiente do aplicativo para usar a identidade correta e solicita tokens de acesso conforme necessário. DefaultAzureCredential simplifica a autenticação para aplicativos implantados no Azure Para obter mais informações, consulte DefaultAzureCredential.

Exemplo: A implementação de referência usa a classe durante a DefaultAzureCredential inicialização para habilitar o uso de identidade gerenciada entre a API da Web e o Cofre da Chave (consulte o código a seguir).

builder.Configuration.AddAzureAppConfiguration(options =>
{
     options
        .Connect(new Uri(builder.Configuration["Api:AppConfig:Uri"]), new DefaultAzureCredential())
        .ConfigureKeyVault(kv =>
        {
            // Some of the values coming from Azure App Configuration are stored Key Vault. Use
            // the managed identity of this host for the authentication.
            kv.SetCredential(new DefaultAzureCredential());
        });
});

Use a infraestrutura como código para criar identidades gerenciadas

Você deve usar modelos Bicep para criar e configurar a infraestrutura do Azure para dar suporte a identidades gerenciadas. As identidades gerenciadas não usam segredos ou senhas, portanto, você não precisa do Cofre de Chaves ou de uma estratégia de rotação secreta para garantir a integridade. Você pode armazenar as cadeias de conexão no Serviço de Configuração do Aplicativo.

Exemplo: A implementação de referência usa modelos Bicep para (1) criar a identidade gerenciada, (2) associar a identidade ao aplicativo Web e (3) conceder a permissão de identidade para acessar o banco de dados SQL. O Authentication argumento na cadeia de conexão informa a biblioteca de cliente da Microsoft para se conectar com uma identidade gerenciada (consulte o código a seguir).

    Server=tcp:my-sql-server.database.windows.net,1433;Initial Catalog=my-sql-database;Authentication=Active Directory Default

Para obter mais informações, consulte Conectar-se ao banco de dados SQL do Serviço de Aplicativo .NET.

Use um repositório central de segredos para gerenciar segredos

Quando você move seu aplicativo para a nuvem, use o Azure Key Vault para armazenar com segurança todos esses segredos. Esse repositório centralizado oferece armazenamento seguro, rotação de chaves, auditoria de acesso e monitoramento de serviços que não suportam identidades gerenciadas. Para configurações de aplicativos, a Configuração do Aplicativo do Azure é recomendada.

Exemplo: A implementação de referência armazena os seguintes segredos no Cofre de Chaves: (1) nome de usuário e senha do banco de dados PostgreSQL, (2) senha do Cache Redis e (3) o segredo do cliente para o ID do Microsoft Entra associado à implementação da Biblioteca de Autenticação da Microsoft (MSAL).

Não coloque o Cofre de Chaves no fluxo de solicitações HTTP

Carregue segredos do Cofre da Chave na inicialização do aplicativo em vez de durante cada solicitação HTTP. O Cofre de Chaves destina-se a armazenar e recuperar dados confidenciais com segurança durante a implantação. O acesso de alta frequência em solicitações HTTP pode exceder os recursos de taxa de transferência do Key Vault, levando a limitações de solicitação e erros de código de status HTTP 429. Para obter mais informações, consulte Limites de transação do Key Vault.

Use um método para acessar segredos no Cofre da Chave

Ao configurar um aplicativo Web para acessar segredos no Cofre da Chave, você tem duas opções principais:

  • Configuração do Aplicativo do Serviço de Aplicativo: use uma configuração de aplicativo no Serviço de Aplicativo para injetar o segredo diretamente como uma variável de ambiente.

  • Referência de segredo direto: faça referência direta ao segredo dentro do código do aplicativo. Adicione uma referência específica no arquivo de propriedades do seu aplicativo, como application.properties para aplicativos Java, para que seu aplicativo se comunique com o Key Vault.

É importante escolher um desses métodos e mantê-lo para simplicidade e evitar complexidade desnecessária.

Prefira métodos de acesso temporário

Use permissões temporárias para se proteger contra acesso não autorizado e violações. Use assinaturas de acesso compartilhado (SASs) para acesso temporário. Use a SAS de delegação de usuários para maximizar a segurança ao conceder acesso temporário. É o único SAS que usa credenciais do Microsoft Entra e não requer uma chave de conta de armazenamento.

Utilizar pontos finais privados

Use pontos de extremidade privados em todos os ambientes de produção para todos os serviços do Azure com suporte. Os pontos de extremidade privados fornecem conexões privadas entre recursos em uma rede virtual do Azure e os serviços do Azure. Por padrão, a comunicação com a maioria dos serviços do Azure atravessa a Internet pública. Os pontos de extremidade privados não exigem alterações de código, configurações de aplicativos ou cadeias de conexão. Para obter mais informações, consulte Como criar um ponto de extremidade privado e Práticas recomendadas para segurança de ponto de extremidade.

Exemplo: Configuração de Aplicativo do Azure, Banco de Dados SQL do Azure, Cache do Azure para Redis, Armazenamento do Azure, Serviço de Aplicativo do Azure e Cofre da Chave usam um ponto de extremidade privado.

Use o firewall de aplicativos da Web e restrinja o tráfego de entrada da Internet

Todo o tráfego de entrada da Internet para o aplicativo Web deve passar por um firewall de aplicativo Web para proteger contra explorações comuns da Web. Força todo o tráfego de entrada da Internet a passar pelo balanceador de carga público, se tiver um, e pelo firewall do aplicativo Web.

Exemplo: A implementação de referência força todo o tráfego de entrada da Internet através do Front Door e do Azure Web Application Firewall. Na produção, preserve o nome do host HTTP original.

Configurar segurança de base de dados

O acesso em nível de administrador ao banco de dados concede permissões para executar operações privilegiadas. As operações privilegiadas incluem a criação e exclusão de bancos de dados, a modificação de esquemas de tabela ou a alteração de permissões de usuário. Os desenvolvedores geralmente precisam de acesso em nível de administrador para manter o banco de dados ou solucionar problemas.

  • Evite permissões permanentes elevadas. Você só deve conceder aos desenvolvedores acesso just-in-time para executar operações privilegiadas. Com o acesso just-in-time, os usuários recebem permissões temporárias para executar tarefas privilegiadas

  • Não dê permissões elevadas ao aplicativo. Você não deve conceder acesso de nível de administrador à identidade do aplicativo. Você deve configurar o acesso com privilégios mínimos para o aplicativo ao banco de dados. Ele limita o raio de explosão de bugs e violações de segurança.

Otimização de custos

A otimização de custos consiste em procurar formas de reduzir despesas desnecessárias e despesas gerais de gestão. Para obter mais informações, consulte a lista de verificação de revisão de design para otimização de custos. O padrão Reliable Web App implementa técnicas de direitos, dimensionamento automático e uso eficiente de recursos para um aplicativo Web com custo otimizado.

Recursos de tamanho certo para cada ambiente

Entenda as diferentes camadas de desempenho dos serviços do Azure e use apenas a SKU apropriada para as necessidades de cada ambiente. Os ambientes de produção precisam de SKUs que atendam aos contratos de nível de serviço (SLA), aos recursos e à escala necessários para a produção. Os ambientes que não são de produção normalmente não precisam dos mesmos recursos. Para economias extras, considere as opções de preços de Desenvolvimento/Teste do Azure, Reservas do Azure e planos de economia do Azure para computação.

Exemplo: A implementação de referência usa parâmetros Bicep para acionar configurações de implantação de recursos. Um desses parâmetros indica as camadas de recursos (SKUs) a serem implantadas. O aplicativo Web usa as SKUs mais eficientes e caras para os ambientes de produção e as SKUs mais baratas para o ambiente de não produção (consulte o código a seguir).

var redisCacheSkuName = isProd ? 'Standard' : 'Basic'
var redisCacheFamilyName = isProd ? 'C' : 'C'
var redisCacheCapacity = isProd ? 1 : 0

Utilizar dimensionamento automático

O dimensionamento automático automatiza o dimensionamento horizontal para ambientes de produção. Dimensionamento automático com base em métricas de desempenho. Os gatilhos de desempenho de utilização da CPU são um bom ponto de partida se você não entender os critérios de dimensionamento do seu aplicativo. Você precisa configurar e adaptar gatilhos de dimensionamento (CPU, RAM, rede e disco) para corresponder ao comportamento do seu aplicativo Web. Não dimensione verticalmente para atender às mudanças frequentes na demanda. É menos eficiente em termos de custos. Para obter mais informações, consulte Dimensionamento no Serviço de Aplicativo do Azure e Dimensionamento automático no Microsoft Azure.

Exemplo: A implementação de referência usa a seguinte configuração no modelo Bicep. Ele cria uma regra de dimensionamento automático para o Serviço de Aplicativo do Azure. A regra pode ser dimensionada para até 10 instâncias e assume como padrão uma instância. Ele usa o uso da CPU como o gatilho para escalar para dentro e para fora. A plataforma de hospedagem de aplicativos da Web é dimensionada em 85% de uso da CPU e em 60%. A configuração de expansão de 85%, em vez de uma porcentagem mais próxima de 100%, fornece um buffer para proteger contra o tráfego acumulado de usuários causado por sessões adesivas. Ele também protege contra altas explosões de tráfego, dimensionando cedo para evitar o uso máximo da CPU. Essas regras de dimensionamento automático não são universais (consulte o código a seguir).

resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (autoScaleSettings != null) { 
  name: '${name}-autoscale' 
  location: location 
  tags: tags 
  properties: { 
    targetResourceUri: appServicePlan.id 
    enabled: true 
    profiles: [ 
      { 
        name: 'Auto created scale condition' 
        capacity: { 
          minimum: string(zoneRedundant ? 3 : autoScaleSettings!.minCapacity) 
          maximum: string(autoScaleSettings!.maxCapacity) 
          default: string(zoneRedundant ? 3 : autoScaleSettings!.minCapacity) 
        } 
        rules: [ 
          ... 
        ] 
      } 
    ] 
  } 
}

Utilize os recursos de forma eficiente

  • Use serviços compartilhados. Centralizar e compartilhar certos recursos proporciona otimização de custos e menor sobrecarga de gerenciamento. Coloque recursos de rede compartilhados na rede virtual do hub.

    Exemplo: A implementação de referência coloca o Firewall do Azure, o Azure Bastion e o Cofre da Chave na rede virtual do hub.

  • Exclua ambientes não utilizados. Exclua ambientes que não sejam de produção após o expediente ou durante feriados para otimizar os custos. Você pode usar a infraestrutura como código para excluir recursos do Azure e ambientes inteiros. Remova a declaração do recurso que você deseja excluir do modelo Bicep. Use a operação hipotética para visualizar as alterações antes que elas entrem em vigor. Faça backup dos dados de que precisa mais tarde. Entenda as dependências do recurso que você está excluindo. Se houver dependências, talvez seja necessário atualizar ou remover esses recursos também. Para obter mais informações, consulte Operação hipotética de implantação do Bícep.

  • Funcionalidade de colocalização. Onde houver capacidade ociosa, colocalize recursos e funcionalidades do aplicativo em um único recurso do Azure. Por exemplo, vários aplicativos Web podem usar um único servidor (Plano do Serviço de Aplicativo) ou um único cache pode suportar vários tipos de dados.

    Exemplo: A implementação de referência usa uma única instância do Cache do Azure para Redis para gerenciamento de sessão em aplicativos Web front-end (armazenamento de carrinho e tokens MSAL) e back-end (armazenamento de dados de Próximos Concertos). Ele opta pelo menor Redis SKU, oferecendo mais do que a capacidade necessária, utilizada de forma eficiente empregando vários tipos de dados para controlar os custos.

Excelência operacional

A excelência operacional abrange os processos operacionais que implantam um aplicativo e o mantêm em execução na produção. Para obter mais informações, consulte a lista de verificação de revisão de design para excelência operacional. O padrão Reliable Web App implementa a infraestrutura como código para implantações de infraestrutura e monitoramento para observabilidade.

Automatize a implantação

Use um pipeline de CI/CD para implantar alterações do controle do código-fonte para a produção. Se você estiver usando o Azure DevOps, deverá usar o Azure Pipelines. Se você estiver usando o GitHub, use as ações do GitHub. O Azure suporta modelo ARM (JSON), Bíceps e Terraform e tem modelos para cada recurso do Azure Para obter mais informações, consulte Bicep, Azure Resource Manager e modelos Terraform e Infraestrutura repetível.

Exemplo: A implementação de referência usa a CLI de Desenvolvimento do Azure e a infraestrutura como código (modelos Bicep) para criar recursos do Azure, configurar a configuração e implantar os recursos necessários.

Configurar a monitorização

Para monitorar seu aplicativo Web, colete e analise métricas e logs do código do aplicativo, da infraestrutura (tempo de execução) e da plataforma (recursos do Azure). Adicione uma configuração de diagnóstico para cada recurso do Azure em sua arquitetura. Cada serviço do Azure tem um conjunto diferente de logs e métricas que você pode capturar. Para obter mais informações, consulte Monitorar a plataforma e Monitorar o Serviço de Aplicativo.

Monitorar métricas da linha de base

Use o Azure Application Insights para controlar métricas de linha de base, como taxa de transferência de solicitação, duração média de solicitação, erros e monitoramento de dependência. Use AddApplicationInsightsTelemetry a partir do pacote Microsoft.ApplicationInsights.AspNetCore NuGet para habilitar a coleta de telemetria. Para obter mais informações, consulte Habilitar telemetria do Application Insights e injeção de dependência no .NET.

Exemplo: A implementação de referência usa código para configurar métricas de linha de base no Application Insights (consulte o código a seguir).

public void ConfigureServices(IServiceCollection services)
{
   ...
   services.AddApplicationInsightsTelemetry(Configuration["App:Api:ApplicationInsights:ConnectionString"]);
   ...
}

Crie telemetria personalizada conforme necessário

Use o Application Insights para coletar telemetria personalizada para entender melhor os usuários do aplicativo Web. Crie uma instância da TelemetryClient classe e use os TelemetryClient métodos para criar a métrica correta. Transforme a consulta em um widget do Painel do Azure.

Exemplo: A implementação de referência adiciona métricas que ajudam a equipe de operações a identificar que o aplicativo Web está concluindo as transações com êxito. Ele valida que o aplicativo Web está on-line monitorando se os clientes podem fazer pedidos, não medindo o número de solicitações ou o uso da CPU. A implementação de referência usa TelemetryClient via injeção de dependência e o método para coletar telemetria TrackEvent em eventos relacionados à atividade do carrinho. A telemetria rastreia os tíquetes que os usuários adicionam, removem e compram (consulte o código a seguir).

  • AddToCart Conta quantas vezes os usuários adicionam um determinado ticket (ConcertID) ao carrinho.
  • RemoveFromCart Registra tíquetes que os usuários removem do carrinho.
  • CheckoutCart Regista um evento sempre que um utilizador compra um bilhete.

this.telemetryClient.TrackEvent Conta os bilhetes adicionados ao carrinho. Ele fornece o nome do evento (AddToCart) e especifica um dicionário que tem o concertId e count (consulte o código a seguir).

this.telemetryClient.TrackEvent("AddToCart", new Dictionary<string, string> {
    { "ConcertId", concertId.ToString() },
    { "Count", count.ToString() }
});

Para obter mais informações, consulte:

Reúna métricas baseadas em log

Acompanhe as métricas baseadas em log para obter mais visibilidade sobre a integridade e as métricas essenciais do aplicativo. Você pode usar consultas KQL (Kusto Query Language) no Application Insights para localizar e organizar dados. Para obter mais informações, consulte Métricas baseadas em log do Azure Application Insights e Métricas pré-agregadas e baseadas em log no Application Insights.

Habilitar o diagnóstico da plataforma

Uma configuração de diagnóstico no Azure permite especificar os logs e métricas da plataforma que você deseja coletar e onde armazená-los. Os logs da plataforma são logs internos que fornecem informações de diagnóstico e auditoria. Você pode habilitar o diagnóstico de plataforma para a maioria dos serviços do Azure, mas cada serviço define suas próprias categorias de log. Diferentes serviços do Azure têm categorias de log para escolher.

  • Habilite o diagnóstico para todos os serviços suportados. Os serviços do Azure criam logs de plataforma automaticamente, mas o serviço não os armazena automaticamente. Você deve habilitar a configuração de diagnóstico para cada serviço e habilitá-la para cada serviço do Azure que dá suporte a diagnósticos.

  • Envie diagnósticos para o mesmo destino que os logs do aplicativo. Ao habilitar o diagnóstico, você escolhe os logs que deseja coletar e para onde enviá-los. Você deve enviar os logs da plataforma para o mesmo destino que os logs do aplicativo para que possa correlacionar os dois conjuntos de dados.

Eficiência de desempenho

Eficiência de desempenho é a capacidade da sua carga de trabalho para dimensionar para satisfazer as exigências que os utilizadores lhe colocam de forma eficiente. Para obter mais informações, consulte a Lista de verificação de revisão de design para Eficiência de desempenho. O padrão Reliable Web App usa o padrão Cache-Aside para minimizar a latência de dados altamente solicitados.

Usar o padrão Cache-Aside

O padrão Cache-Aside é uma estratégia de cache que melhora o gerenciamento de dados na memória. O padrão atribui ao aplicativo a responsabilidade de lidar com solicitações de dados e garantir a consistência entre o cache e um armazenamento persistente, como um banco de dados. Quando o aplicativo Web recebe uma solicitação de dados, ele primeiro pesquisa o cache. Se os dados estiverem ausentes, ele os recuperará do banco de dados, responderá à solicitação e atualizará o cache adequadamente. Essa abordagem reduz os tempos de resposta, melhora a taxa de transferência e reduz a necessidade de mais escala. Ele também reforça a disponibilidade do serviço, reduzindo a carga no armazenamento de dados principal e minimizando os riscos de paralisação.

Exemplo: A implementação de referência melhora a eficiência do aplicativo armazenando em cache dados críticos, como informações para os próximos shows, cruciais para a venda de ingressos. Ele usa o cache de memória distribuída do ASP.NET Core para armazenamento de itens na memória. O aplicativo usa automaticamente o Cache Redis do Azure quando encontra uma cadeia de conexão específica. Ele também suporta ambientes de desenvolvimento local sem Redis para simplificar a configuração e reduzir custos e complexidade. O método (AddAzureCacheForRedis) configura o aplicativo para usar o Cache Redis do Azure (consulte o código a seguir).

private void AddAzureCacheForRedis(IServiceCollection services)
{
    if (!string.IsNullOrWhiteSpace(Configuration["App:RedisCache:ConnectionString"]))
    {
        services.AddStackExchangeRedisCache(options =>
        {
            options.Configuration = Configuration["App:RedisCache:ConnectionString"];
        });
    }
    else
    {
        services.AddDistributedMemoryCache();
    }
}

Para obter mais informações, consulte Cache distribuído no ASP.NET Core e Método AddDistributedMemoryCache.

Armazene em cache dados de alta necessidade

Priorize o cache para os dados acessados com mais frequência. Identifique os principais pontos de dados que impulsionam o envolvimento do usuário e o desempenho do sistema. Implemente estratégias de cache especificamente para essas áreas para otimizar a eficácia do padrão Cache-Side, reduzindo significativamente a latência e a carga do banco de dados. Use o Azure Monitor para controlar a CPU, a memória e o armazenamento do banco de dados. Essas métricas ajudam a determinar se você pode usar uma SKU de banco de dados menor.

Exemplo: A implementação de referência armazena em cache os dados que suportam os Próximos Concertos. A página Próximos Concertos cria a maioria das consultas ao Banco de Dados SQL e produz uma saída consistente para cada visita. O padrão Cache-Aside armazena em cache os dados após a primeira solicitação para esta página para reduzir a carga no banco de dados. O código a seguir usa o GetUpcomingConcertsAsync método para extrair dados do Banco de dados SQL para o cache Redis. O método preenche o cache com os concertos mais recentes. O método filtra por tempo, classifica os dados e retorna os dados ao controlador para exibir os resultados (consulte o código a seguir).

public async Task<ICollection<Concert>> GetUpcomingConcertsAsync(int count)
{
    IList<Concert>? concerts;
    var concertsJson = await this.cache.GetStringAsync(CacheKeys.UpcomingConcerts);
    if (concertsJson != null)
    {
        // There is cached data. Deserialize the JSON data.
        concerts = JsonSerializer.Deserialize<IList<Concert>>(concertsJson);
    }
    else
    {
        // There's nothing in the cache. Retrieve data from the repository and cache it for one hour.
        concerts = await this.database.Concerts.AsNoTracking()
            .Where(c => c.StartTime > DateTimeOffset.UtcNow && c.IsVisible)
            .OrderBy(c => c.StartTime)
            .Take(count)
            .ToListAsync();
        concertsJson = JsonSerializer.Serialize(concerts);
        var cacheOptions = new DistributedCacheEntryOptions {
            AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
        };
        await this.cache.SetStringAsync(CacheKeys.UpcomingConcerts, concertsJson, cacheOptions);
    }
    return concerts ?? new List<Concert>();
}

Manter os dados de cache atualizados

Agende atualizações regulares de cache para sincronizar com as alterações mais recentes do banco de dados. Determine a taxa de atualização ideal com base na volatilidade dos dados e nas necessidades do usuário. Essa prática garante que o aplicativo use o padrão Cache-Aside para fornecer acesso rápido e informações atuais.

Exemplo: A implementação de referência armazena dados em cache apenas por uma hora. Ele tem um processo para limpar a chave de cache quando os dados mudam. O CreateConcertAsync método limpa a chave de cache (consulte o código a seguir).

public async Task<CreateResult> CreateConcertAsync(Concert newConcert)
{
    database.Add(newConcert);
    await this.database.SaveChangesAsync();
    this.cache.Remove(CacheKeys.UpcomingConcerts);
    return CreateResult.SuccessResult(newConcert.Id);
}

Garantir a consistência dos dados

Implemente mecanismos para atualizar o cache imediatamente após qualquer operação de gravação do banco de dados. Use atualizações controladas por eventos ou classes dedicadas de gerenciamento de dados para garantir a coerência do cache. A sincronização consistente do cache com as modificações do banco de dados é fundamental para o padrão Cache-Side.

Exemplo: A implementação de referência usa o UpdateConcertAsync método para manter os dados no cache consistentes (consulte o código a seguir).

public async Task<UpdateResult> UpdateConcertAsync(Concert existingConcert), 
{
   database.Update(existingConcert);
   await database.SaveChangesAsync();
   this.cache.Remove(CacheKeys.UpcomingConcerts);
   return UpdateResult.SuccessResult();
}

Testar o desempenho do banco de dados

O desempenho do banco de dados pode afetar o desempenho e a escalabilidade de um aplicativo. É importante testar o desempenho do seu banco de dados para garantir que ele seja otimizado. Algumas considerações importantes incluem a escolha da região de nuvem certa, o pool de conexões, o padrão de cache-aside e a otimização de consultas.

  • Teste saltos de rede. Mover um aplicativo para a nuvem pode introduzir saltos de rede e latência extras ao seu banco de dados. Você deve testar os saltos extras que o novo ambiente de nuvem introduz.

  • Estabeleça uma linha de base de desempenho. Você deve usar métricas de desempenho locais como a linha de base inicial para comparar o desempenho do aplicativo na nuvem.

Próximos passos

Implante a implementação de referência seguindo as instruções no repositório GitHub. Use os recursos a seguir para saber mais sobre aplicativos .NET, aplicativos Web, práticas recomendadas de nuvem e migração.

Atualizando aplicativos do .NET Framework

A implementação de referência é implantada em um Serviço de Aplicativo que executa o Windows, mas pode ser executado no Linux. A plataforma Windows do Serviço de Aplicativo permite que você mova aplicativos Web do .NET Framework para o Azure sem atualizar para versões mais recentes da estrutura. Para obter informações sobre planos do Linux App Service ou novos recursos e melhorias de desempenho adicionados às versões mais recentes do .NET, consulte as diretrizes a seguir.

Introdução aos aplicativos Web no Azure

Para obter uma introdução prática aos aplicativos Web .NET no Azure, consulte este guia para implantar um aplicativo Web .NET básico.

Práticas recomendadas na nuvem

Para obter orientações de arquitetura e adoção do Azure, consulte:

  • Estrutura de adoção de nuvem. Pode ajudar sua organização a preparar e executar uma estratégia para criar soluções no Azure.
  • Estrutura bem arquitetada. Um conjunto de princípios orientadores que podem ser usados para melhorar a qualidade de uma carga de trabalho.

Para aplicativos que exigem um SLO maior do que o padrão Reliable Web App, consulte cargas de trabalho de missão crítica.

Documentação de orientação de migração

As seguintes ferramentas e recursos podem ajudá-lo a migrar recursos locais para o Azure.

  • O Azure Migrate fornece um serviço simplificado de migração, modernização e otimização para o Azure que lida com a avaliação e migração de aplicativos Web, SQL Server e máquinas virtuais.
  • Os Guias de Migração de Banco de Dados do Azure fornecem recursos para diferentes tipos de banco de dados e diferentes ferramentas projetadas para seu cenário de migração.
  • O acelerador de zona de aterrissagem do Serviço de Aplicativo do Azure fornece orientação para proteger e dimensionar implantações do Serviço de Aplicativo.
  • Azure Migrate aplicativo e avaliação de código