Delen via


Statuscontrole

Tip

Deze inhoud is een fragment uit het eBook, .NET Microservices Architecture for Containerized .NET Applications, beschikbaar op .NET Docs of als een gratis downloadbare PDF die offline kan worden gelezen.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

Statuscontrole kan bijna realtime informatie over de status van uw containers en microservices toestaan. Statuscontrole is essentieel voor meerdere aspecten van operationele microservices en is vooral belangrijk wanneer orchestrators gedeeltelijke toepassingsupgrades uitvoeren in fasen, zoals later wordt uitgelegd.

Op microservices gebaseerde toepassingen maken vaak gebruik van heartbeats of statuscontroles om hun prestatiemonitors, planners en orchestrators in staat te stellen om de vele services bij te houden. Als services een soort 'Ik leef'-signaal niet kunnen verzenden, hetzij op aanvraag of volgens een planning, kan uw toepassing risico's ondervinden wanneer u updates implementeert, of kan deze fouten mogelijk te laat detecteren en trapsgewijze fouten die kunnen eindigen bij grote storingen niet stoppen.

In het typische model verzenden services rapporten over hun status en worden die gegevens samengevoegd om een algemeen overzicht te geven van de status van uw toepassing. Als u een orchestrator gebruikt, kunt u statusinformatie verstrekken aan het cluster van uw orchestrator, zodat het cluster dienovereenkomstig kan handelen. Als u investeert in kwaliteitsrapportage die is aangepast voor uw toepassing, kunt u problemen voor uw actieve toepassing veel eenvoudiger detecteren en oplossen.

Statuscontroles implementeren in ASP.NET Core-services

Wanneer u een ASP.NET Core-microservice of webtoepassing ontwikkelt, kunt u de ingebouwde functie voor statuscontroles gebruiken die is uitgebracht in ASP .NET Core 2.2 (Microsoft.Extensions.Diagnostics.HealthChecks). Net als veel ASP.NET Kernfuncties worden statuscontroles geleverd met een set services en middleware.

Statuscontroleservices en middleware zijn eenvoudig te gebruiken en bieden mogelijkheden waarmee u kunt controleren of een externe resource die nodig is voor uw toepassing (zoals een SQL Server-database of een externe API) goed werkt. Wanneer u deze functie gebruikt, kunt u ook bepalen wat het betekent dat de resource in orde is, zoals we later uitleggen.

Als u deze functie effectief wilt gebruiken, moet u eerst services in uw microservices configureren. Ten tweede hebt u een front-endtoepassing nodig waarmee query's worden uitgevoerd voor de statusrapporten. Deze front-endtoepassing kan een aangepaste rapportagetoepassing zijn of een orchestrator zelf die dienovereenkomstig kan reageren op de statusstatussen.

De functie HealthChecks gebruiken in uw back-end-ASP.NET microservices

In deze sectie leert u hoe u de functie HealthChecks implementeert in een voorbeeld-ASP.NET Core 8.0-web-API-toepassing wanneer u het pakket Microsoft.Extensions.Diagnostics.HealthChecks gebruikt. De implementatie van deze functie in grootschalige microservices, zoals de eShopOnContainers, wordt in de volgende sectie uitgelegd.

Om te beginnen moet u definiëren wat een gezonde status is voor elke microservice. In de voorbeeldtoepassing definiëren we dat de microservice in orde is als de API toegankelijk is via HTTP en de bijbehorende SQL Server-database ook beschikbaar is.

In .NET 8 kunt u met de ingebouwde API's de services configureren, een statuscontrole voor de microservice en de afhankelijke SQL Server-database op deze manier toevoegen:

// 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" });

In de vorige code configureert de services.AddHealthChecks() methode een eenvoudige HTTP-controle die een statuscode 200 retourneert met 'In orde'. Verder configureert de AddCheck() extensiemethode een aangepaste SqlConnectionHealthCheck methode die de status van de gerelateerde SQL Database controleert.

De AddCheck() methode voegt een nieuwe statuscontrole toe met een opgegeven naam en de implementatie van het type IHealthCheck. U kunt meerdere statuscontroles toevoegen met de methode AddCheck, zodat een microservice geen status 'in orde' krijgt totdat alle controles in orde zijn.

SqlConnectionHealthCheckis een aangepaste klasse die een verbindingsreeks als constructorparameter implementeert IHealthChecken een eenvoudige query uitvoert om te controleren of de verbinding met de SQL-database is geslaagd. Deze retourneert HealthCheckResult.Healthy() als de query is uitgevoerd en een FailureStatus met de werkelijke uitzondering wanneer deze mislukt.

// 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();
    }
}

Houd er rekening mee dat in de vorige code Select 1 de query is die wordt gebruikt om de status van de database te controleren. Om de beschikbaarheid van uw microservices te bewaken, voeren orchestrators zoals Kubernetes periodiek statuscontroles uit door aanvragen te verzenden om de microservices te testen. Het is belangrijk om uw databasequery's efficiënt te houden, zodat deze bewerkingen snel zijn en niet resulteren in een hoger gebruik van resources.

Voeg ten slotte een middleware toe die reageert op het URL-pad /hc:

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

app.MapHealthChecks("/hc");

Wanneer het eindpunt <yourmicroservice>/hc wordt aangeroepen, worden alle statuscontroles uitgevoerd die zijn geconfigureerd in de methode in de AddHealthChecks() opstartklasse en wordt het resultaat weergegeven.

HealthChecks-implementatie in eShopOnContainers

Microservices in eShopOnContainers zijn afhankelijk van meerdere services om de taak uit te voeren. De microservice van eShopOnContainers is bijvoorbeeld Catalog.API afhankelijk van veel services, zoals Azure Blob Storage, SQL Server en RabbitMQ. Daarom zijn er verschillende statuscontroles toegevoegd met behulp van de AddCheck() methode. Voor elke afhankelijke service moet een aangepaste IHealthCheck implementatie die de respectieve status definieert, worden toegevoegd.

Het opensource-project AspNetCore.Diagnostics.HealthChecks lost dit probleem op door aangepaste statuscontrole-implementaties te bieden voor elk van deze bedrijfsservices, die zijn gebouwd op .NET 8. Elke statuscontrole is beschikbaar als een afzonderlijk NuGet-pakket dat eenvoudig aan het project kan worden toegevoegd. eShopOnContainers gebruikt ze uitgebreid in alle microservices.

In de Catalog.API microservice zijn bijvoorbeeld de volgende NuGet-pakketten toegevoegd:

Screenshot of the AspNetCore.Diagnostics.HealthChecks NuGet packages.

Afbeelding 8-7. Aangepaste statuscontroles geïmplementeerd in Catalog.API met behulp van AspNetCore.Diagnostics.HealthChecks

In de volgende code worden de implementaties van de statuscontrole toegevoegd voor elke afhankelijke service en wordt de middleware geconfigureerd:

// 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;
}

Voeg ten slotte de HealthCheck-middleware toe om naar het eindpunt '/hc' te luisteren:

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

Query's uitvoeren op uw microservices om te rapporteren over hun status

Wanneer u statuscontroles hebt geconfigureerd zoals beschreven in dit artikel en u de microservice in Docker hebt uitgevoerd, kunt u rechtstreeks vanuit een browser controleren of deze in orde is. U moet de containerpoort publiceren in de Docker-host, zodat u toegang hebt tot de container via het ip-adres van de externe Docker-host of via host.docker.internal, zoals wordt weergegeven in afbeelding 8-8.

Screenshot of the JSON response returned by a health check.

Afbeelding 8-8. De status van één service controleren vanuit een browser

In die test kunt u zien dat de Catalog.API microservice (uitgevoerd op poort 5101) in orde is en http-status 200 en statusinformatie retourneert in JSON. De service heeft ook de status gecontroleerd van de afhankelijkheid van de SQL Server-database en RabbitMQ, dus de statuscontrole heeft zichzelf gerapporteerd als in orde.

Watchdogs gebruiken

Een watchdog is een afzonderlijke service die de status en belasting van services kan bekijken en de status van de microservices kan rapporteren door een query uit te voeren op de HealthChecks bibliotheek die eerder is geïntroduceerd. Dit kan helpen bij het voorkomen van fouten die niet worden gedetecteerd op basis van de weergave van één service. Watchdogs zijn ook een goede plek om code te hosten die herstelacties kan uitvoeren voor bekende voorwaarden zonder tussenkomst van de gebruiker.

Het voorbeeld eShopOnContainers bevat een webpagina met voorbeeldstatuscontrolerapporten, zoals weergegeven in afbeelding 8-9. Dit is de eenvoudigste watchdog die u zou kunnen hebben, omdat deze alleen de status van de microservices en webtoepassingen in eShopOnContainers weergeeft. Meestal voert een watchdog ook acties uit wanneer er beschadigde statussen worden gedetecteerd.

Gelukkig biedt AspNetCore.Diagnostics.HealthChecks ook het NuGet-pakket AspNetCore.HealthChecks.UI dat kan worden gebruikt om de resultaten van de statuscontrole van de geconfigureerde URI's weer te geven.

Screenshot of the Health Checks UI eShopOnContainers health statuses.

Afbeelding 8-9. Voorbeeld van statuscontrolerapport in eShopOnContainers

Samengevat voert deze watchdog-service een query uit op het eindpunt '/hc' van elke microservice. Hiermee worden alle statuscontroles uitgevoerd die erin zijn gedefinieerd en wordt een algehele status geretourneerd, afhankelijk van al deze controles. De HealthChecksUI is eenvoudig te gebruiken met enkele configuratievermeldingen en twee regels code die moeten worden toegevoegd aan de Startup.cs van de watchdog-service.

Voorbeeldconfiguratiebestand voor de gebruikersinterface voor statuscontrole:

// 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 bestand dat HealthChecksUI toevoegt:

// 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");

Statuscontroles bij het gebruik van orchestrators

Om de beschikbaarheid van uw microservices te bewaken, voeren orchestrators zoals Kubernetes en Service Fabric periodiek statuscontroles uit door aanvragen te verzenden om de microservices te testen. Wanneer een orchestrator bepaalt dat een service/container niet in orde is, stopt de routering van aanvragen naar dat exemplaar. Er wordt meestal ook een nieuw exemplaar van die container gemaakt.

De meeste orchestrators kunnen bijvoorbeeld statuscontroles gebruiken om implementaties zonder downtime te beheren. Alleen wanneer de status van een service/container in orde verandert, start de orchestrator het routeren van verkeer naar service-/containerinstanties.

Statuscontrole is vooral belangrijk wanneer een orchestrator een toepassingsupgrade uitvoert. Sommige orchestrators (zoals Azure Service Fabric) werken services in fasen bij. Ze kunnen bijvoorbeeld een vijfde van het clusteroppervlak bijwerken voor elke toepassingsupgrade. De set knooppunten die tegelijkertijd wordt bijgewerkt, wordt een upgradedomein genoemd. Nadat elk upgradedomein is bijgewerkt en beschikbaar is voor gebruikers, moet dat upgradedomein statuscontroles doorgeven voordat de implementatie wordt verplaatst naar het volgende upgradedomein.

Een ander aspect van de servicestatus is het rapporteren van metrische gegevens van de service. Dit is een geavanceerde mogelijkheid van het statusmodel van sommige orchestrators, zoals Service Fabric. Metrische gegevens zijn belangrijk bij het gebruik van een orchestrator, omdat ze worden gebruikt om het resourcegebruik te verdelen. Metrische gegevens kunnen ook een indicator van de systeemstatus zijn. U hebt bijvoorbeeld een toepassing met veel microservices en elk exemplaar rapporteert een metrische waarde voor aanvragen per seconde (RPS). Als een service meer resources gebruikt (geheugen, processor, enzovoort) dan een andere service, kan de orchestrator service-exemplaren in het cluster verplaatsen om zelfs resourcegebruik te behouden.

Houd er rekening mee dat Azure Service Fabric een eigen Health Monitoring-model biedt, wat geavanceerder is dan eenvoudige statuscontroles.

Geavanceerde bewaking: visualisatie, analyse en waarschuwingen

Het laatste deel van de bewaking is het visualiseren van de gebeurtenisstroom, het rapporteren van serviceprestaties en het waarschuwen wanneer er een probleem wordt gedetecteerd. U kunt verschillende oplossingen gebruiken voor dit aspect van bewaking.

U kunt eenvoudige aangepaste toepassingen gebruiken met de status van uw services, zoals de aangepaste pagina die wordt weergegeven bij het uitleggen van aspNetCore.Diagnostics.HealthChecks. U kunt ook geavanceerdere hulpprogramma's zoals Azure Monitor gebruiken om waarschuwingen te genereren op basis van de stroom gebeurtenissen.

Ten slotte kunt u, als u alle gebeurtenisstreams opslaat, Microsoft Power BI of andere oplossingen zoals Kibana of Splunk gebruiken om de gegevens te visualiseren.

Aanvullende bronnen