Partilhar via


Monitorização do estado de funcionamento

Gorjeta

Este conteúdo é um trecho do eBook, .NET Microservices Architecture for Containerized .NET Applications, disponível no .NET Docs ou como um PDF para download gratuito que pode ser lido offline.

Miniatura da capa do eBook .NET Microservices Architecture for Containerized .NET Applications.

O monitoramento de integridade pode permitir informações quase em tempo real sobre o estado de seus contêineres e microsserviços. O monitoramento de integridade é crítico para vários aspetos da operação de microsserviços e é especialmente importante quando os orquestradores executam atualizações parciais de aplicativos em fases, conforme explicado mais adiante.

Os aplicativos baseados em microsserviços geralmente usam pulsações ou verificações de integridade para permitir que seus monitores de desempenho, agendadores e orquestradores acompanhem a infinidade de serviços. Se os serviços não puderem enviar algum tipo de sinal de "Estou vivo", seja sob demanda ou em um cronograma, seu aplicativo poderá enfrentar riscos ao implantar atualizações ou poderá apenas detetar falhas tarde demais e não ser capaz de interromper falhas em cascata que podem acabar em grandes interrupções.

No modelo típico, os serviços enviam relatórios sobre seu status e essas informações são agregadas para fornecer uma visão geral do estado de integridade do seu aplicativo. Se você estiver usando um orquestrador, poderá fornecer informações de integridade ao cluster do orquestrador, para que o cluster possa agir de acordo. Se você investir em relatórios de integridade de alta qualidade personalizados para seu aplicativo, poderá detetar e corrigir problemas para seu aplicativo em execução com muito mais facilidade.

Implementar verificações de integridade em ASP.NET serviços principais

Ao desenvolver um microsserviço ou aplicativo Web do ASP.NET Core, você pode usar o recurso interno de verificações de integridade que foi lançado no ASP .NET Core 2.2 (Microsoft.Extensions.Diagnostics.HealthChecks). Como muitos recursos ASP.NET Core, as verificações de integridade vêm com um conjunto de serviços e um middleware.

Os serviços de verificação de integridade e o middleware são fáceis de usar e fornecem recursos que permitem validar se algum recurso externo necessário para seu aplicativo (como um banco de dados do SQL Server ou uma API remota) está funcionando corretamente. Ao usar esse recurso, você também pode decidir o que significa que o recurso está íntegro, como explicaremos mais adiante.

Para usar esse recurso de forma eficaz, você precisa primeiro configurar serviços em seus microsserviços. Em segundo lugar, você precisa de um aplicativo front-end que consulte os relatórios de integridade. Esse aplicativo front-end pode ser um aplicativo de relatório personalizado ou pode ser um orquestrador que pode reagir de acordo com os estados de integridade.

Use o recurso HealthChecks em seus microsserviços de back-end ASP.NET

Nesta seção, você aprenderá como implementar o recurso HealthChecks em um exemplo de aplicativo de API Web ASP.NET Core 8.0 ao usar o pacote Microsoft.Extensions.Diagnostics.HealthChecks . A implementação desse recurso em microsserviços de grande escala como o eShopOnContainers é explicada na próxima seção.

Para começar, você precisa definir o que constitui um status saudável para cada microsserviço. No aplicativo de exemplo, definimos que o microsserviço está íntegro se sua API estiver acessível via HTTP e seu banco de dados SQL Server relacionado também estiver disponível.

No .NET 8, com as APIs internas, você pode configurar os serviços, adicionar uma verificação de integridade para o microsserviço e seu banco de dados SQL Server dependente desta maneira:

// Program.cs from .NET 8 Web API sample

//...
// Registers required services for health checks
builder.Services.AddHealthChecks()
    // Add a health check for a SQL Server database
    .AddCheck(
        "OrderingDB-check",
        new SqlConnectionHealthCheck(builder.Configuration["ConnectionString"]),
        HealthStatus.Unhealthy,
        new string[] { "orderingdb" });

No código anterior, o services.AddHealthChecks() método configura uma verificação HTTP básica que retorna um código de status 200 com "Íntegro". Além disso, o AddCheck() método de extensão configura um costume SqlConnectionHealthCheck que verifica a integridade do Banco de dados SQL relacionado.

O AddCheck() método adiciona uma nova verificação de integridade com um nome especificado e a implementação do tipo IHealthCheck. Você pode adicionar várias verificações de integridade usando o método AddCheck, para que um microsserviço não forneça um status "íntegro" até que todas as suas verificações estejam íntegras.

SqlConnectionHealthCheck é uma classe personalizada que implementa o , que usa uma cadeia de IHealthCheckconexão como um parâmetro do construtor e executa uma consulta simples para verificar se a conexão com o banco de dados SQL foi bem-sucedida. Ele retorna HealthCheckResult.Healthy() se a consulta foi executada com êxito e um FailureStatus com a exceção real quando falha.

// Sample SQL Connection Health Check
public class SqlConnectionHealthCheck : IHealthCheck
{
    private const string DefaultTestQuery = "Select 1";

    public string ConnectionString { get; }

    public string TestQuery { get; }

    public SqlConnectionHealthCheck(string connectionString)
        : this(connectionString, testQuery: DefaultTestQuery)
    {
    }

    public SqlConnectionHealthCheck(string connectionString, string testQuery)
    {
        ConnectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
        TestQuery = testQuery;
    }

    public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken))
    {
        using (var connection = new SqlConnection(ConnectionString))
        {
            try
            {
                await connection.OpenAsync(cancellationToken);

                if (TestQuery != null)
                {
                    var command = connection.CreateCommand();
                    command.CommandText = TestQuery;

                    await command.ExecuteNonQueryAsync(cancellationToken);
                }
            }
            catch (DbException ex)
            {
                return new HealthCheckResult(status: context.Registration.FailureStatus, exception: ex);
            }
        }

        return HealthCheckResult.Healthy();
    }
}

Importante

A Microsoft recomenda que você use o fluxo de autenticação mais seguro disponível. Se você estiver se conectando ao SQL do Azure, as Identidades Gerenciadas para recursos do Azure serão o método de autenticação recomendado.

Observe que no código anterior, Select 1 é a consulta usada para verificar a integridade do banco de dados. Para monitorar a disponibilidade de seus microsserviços, orquestradores como o Kubernetes realizam periodicamente verificações de integridade enviando solicitações para testar os microsserviços. É importante manter as consultas de banco de dados eficientes para que essas operações sejam rápidas e não resultem em uma maior utilização de recursos.

Finalmente, adicione um middleware que responda ao caminho /hcurl :

// Program.cs from .NET 8 Web Api sample

app.MapHealthChecks("/hc");

Quando o ponto de extremidade <yourmicroservice>/hc é invocado, ele executa todas as verificações de integridade configuradas no AddHealthChecks() método na classe Startup e mostra o resultado.

Implementação de HealthChecks em eShopOnContainers

Os microsserviços em eShopOnContainers dependem de vários serviços para executar sua tarefa. Por exemplo, o microsserviço do eShopOnContainers depende de muitos serviços, como o Armazenamento de Blobs do Azure, o SQL Server e o Catalog.API RabbitMQ. Portanto, ele tem várias verificações de integridade adicionadas usando o AddCheck() método. Para cada serviço dependente, uma implementação personalizada IHealthCheck que define seu respetivo status de integridade precisaria ser adicionada.

O projeto de código aberto AspNetCore.Diagnostics.HealthChecks resolve esse problema fornecendo implementações personalizadas de verificação de integridade para cada um desses serviços corporativos, que são criados sobre o .NET 8. Cada verificação de integridade está disponível como um pacote NuGet individual que pode ser facilmente adicionado ao projeto. A eShopOnContainers utiliza-os extensivamente em todos os seus microsserviços.

Por exemplo, no Catalog.API microsserviço, os seguintes pacotes NuGet foram adicionados:

Captura de tela dos pacotes NuGet AspNetCore.Diagnostics.HealthChecks.

Figura 8-7. Verificações de integridade personalizadas implementadas em Catalog.API usando AspNetCore.Diagnostics.HealthChecks

No código a seguir, as implementações de verificação de integridade são adicionadas para cada serviço dependente e, em seguida, o middleware é configurado:

// Extension method from Catalog.api microservice
//
public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration)
{
    var accountName = configuration.GetValue<string>("AzureStorageAccountName");
    var accountKey = configuration.GetValue<string>("AzureStorageAccountKey");

    var hcBuilder = services.AddHealthChecks();

    hcBuilder
        .AddSqlServer(
            configuration["ConnectionString"],
            name: "CatalogDB-check",
            tags: new string[] { "catalogdb" });

    if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey))
    {
        hcBuilder
            .AddAzureBlobStorage(
                $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net",
                name: "catalog-storage-check",
                tags: new string[] { "catalogstorage" });
    }
    if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
    {
        hcBuilder
            .AddAzureServiceBusTopic(
                configuration["EventBusConnection"],
                topicName: "eshop_event_bus",
                name: "catalog-servicebus-check",
                tags: new string[] { "servicebus" });
    }
    else
    {
        hcBuilder
            .AddRabbitMQ(
                $"amqp://{configuration["EventBusConnection"]}",
                name: "catalog-rabbitmqbus-check",
                tags: new string[] { "rabbitmqbus" });
    }

    return services;
}

Finalmente, adicione o middleware HealthCheck para ouvir o ponto de extremidade "/hc":

// HealthCheck middleware
app.UseHealthChecks("/hc", new HealthCheckOptions()
{
    Predicate = _ => true,
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});

Consulte seus microsserviços para relatar sobre seu status de integridade

Quando você tiver configurado as verificações de integridade conforme descrito neste artigo e tiver o microsserviço em execução no Docker, poderá verificar diretamente em um navegador se ele está íntegro. Você precisa publicar a porta do contêiner no host do Docker, para que possa acessar o contêiner por meio do IP externo do host do Docker ou através do host.docker.internal, como mostra a figura 8-8.

Captura de tela da resposta JSON retornada por uma verificação de integridade.

Figura 8-8. Verificar o estado de funcionamento de um único serviço a partir de um browser

Nesse teste, você pode ver que o microsserviço (em execução na porta 5101) está íntegro, retornando o status HTTP 200 e informações de Catalog.API status em JSON. O serviço também verificou a integridade de sua dependência de banco de dados do SQL Server e do RabbitMQ, de modo que a verificação de integridade se reportou como íntegra.

Use cães de guarda

Um cão de guarda é um serviço separado que pode observar a integridade e carregar entre serviços, e relatar a integridade sobre os microsserviços consultando com a biblioteca introduzida HealthChecks anteriormente. Isso pode ajudar a evitar erros que não seriam detetados com base na exibição de um único serviço. Os watchdogs também são um bom lugar para hospedar código que pode executar ações de correção para condições conhecidas sem interação do usuário.

O exemplo eShopOnContainers contém uma página da Web que exibe exemplos de relatórios de verificação de integridade, como mostra a Figura 8-9. Este é o cão de guarda mais simples que você poderia ter, uma vez que mostra apenas o estado dos microsserviços e aplicações web em eShopOnContainers. Normalmente, um cão de guarda também toma medidas quando deteta estados insalubres.

Felizmente, o AspNetCore.Diagnostics.HealthChecks também fornece o pacote NuGet AspNetCore.HealthChecks.UI que pode ser usado para exibir os resultados da verificação de integridade dos URIs configurados.

Captura de tela dos status de integridade da interface do usuário de Verificações de Integridade eShopOnContainers.

Figura 8-9. Exemplo de relatório de verificação de integridade no eShopOnContainers

Em resumo, esse serviço de vigilância consulta o ponto de extremidade "/hc" de cada microsserviço. Isso executará todas as verificações de integridade definidas nele e retornará um estado de integridade geral dependendo de todas essas verificações. O HealthChecksUI é fácil de consumir com algumas entradas de configuração e duas linhas de código que precisam ser adicionadas ao Startup.cs do serviço de vigilância.

Exemplo de arquivo de configuração para a interface do usuário de verificação de integridade:

// Configuration
{
  "HealthChecksUI": {
    "HealthChecks": [
      {
        "Name": "Ordering HTTP Check",
        "Uri": "http://host.docker.internal:5102/hc"
      },
      {
        "Name": "Ordering HTTP Background Check",
        "Uri": "http://host.docker.internal:5111/hc"
      },
      //...
    ]}
}

Program.cs arquivo que adiciona HealthChecksUI:

// Program.cs from WebStatus(Watch Dog) service
//
// Registers required services for health checks
builder.Services.AddHealthChecksUI();
// build the app, register other middleware
app.UseHealthChecksUI(config => config.UIPath = "/hc-ui");

Verificações de integridade ao usar orquestradores

Para monitorar a disponibilidade de seus microsserviços, orquestradores como Kubernetes e Service Fabric realizam periodicamente verificações de integridade enviando solicitações para testar os microsserviços. Quando um orquestrador determina que um serviço/contêiner não está íntegro, ele interrompe o roteamento de solicitações para essa instância. Ele também geralmente cria uma nova instância desse contêiner.

Por exemplo, a maioria dos orquestradores pode usar verificações de integridade para gerenciar implantações sem tempo de inatividade. Somente quando o status de um serviço/contêiner mudar para íntegro é que o orquestrador começará a rotear o tráfego para instâncias de serviço/contêiner.

O monitoramento de integridade é especialmente importante quando um orquestrador executa uma atualização de aplicativo. Alguns orquestradores (como o Azure Service Fabric) atualizam os serviços em fases, por exemplo, eles podem atualizar um quinto da superfície do cluster para cada atualização de aplicativo. O conjunto de nós que é atualizado ao mesmo tempo é chamado de domínio de atualização. Depois que cada domínio de atualização tiver sido atualizado e estiver disponível para os usuários, esse domínio de atualização deverá passar por verificações de integridade antes que a implantação seja movida para o próximo domínio de atualização.

Outro aspeto da integridade do serviço é o relatório de métricas do serviço. Esse é um recurso avançado do modelo de integridade de alguns orquestradores, como o Service Fabric. As métricas são importantes ao usar um orquestrador porque são usadas para equilibrar o uso de recursos. As métricas também podem ser um indicador da integridade do sistema. Por exemplo, você pode ter um aplicativo que tenha muitos microsserviços e cada instância relata uma métrica de solicitações por segundo (RPS). Se um serviço estiver usando mais recursos (memória, processador, etc.) do que outro serviço, o orquestrador poderá mover instâncias de serviço no cluster para tentar manter a utilização uniforme dos recursos.

Observe que o Azure Service Fabric fornece seu próprio modelo de Monitoramento de Integridade, que é mais avançado do que simples verificações de integridade.

Monitoramento avançado: visualização, análise e alertas

A parte final do monitoramento é visualizar o fluxo de eventos, gerar relatórios sobre o desempenho do serviço e alertar quando um problema é detetado. Você pode usar diferentes soluções para esse aspeto do monitoramento.

Você pode usar aplicativos personalizados simples mostrando o estado de seus serviços, como a página personalizada mostrada ao explicar o AspNetCore.Diagnostics.HealthChecks. Ou você pode usar ferramentas mais avançadas, como o Azure Monitor , para gerar alertas com base no fluxo de eventos.

Finalmente, se você estiver armazenando todos os fluxos de eventos, poderá usar o Microsoft Power BI ou outras soluções como Kibana ou Splunk para visualizar os dados.

Recursos adicionais