Kontroly stavu v ASP.NET Core

Glenn Condron a Juergen Gutsch

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Důležité

Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

ASP.NET Core nabízí middlewarové kontroly stavu a knihovny pro vytváření sestav stavu komponent infrastruktury aplikací.

Kontroly stavu jsou vystaveny aplikací jako koncové body HTTP. Koncové body kontroly stavu je možné nakonfigurovat pro různé scénáře monitorování v reálném čase:

  • Sondy stavu můžou používat orchestrátory kontejnerů a nástroje pro vyrovnávání zatížení ke kontrole stavu aplikace. Orchestrátor kontejnerů může například reagovat na neúspěšnou kontrolu stavu zastavením postupného nasazení nebo restartováním kontejneru. Nástroj pro vyrovnávání zatížení může reagovat na aplikaci, která není v pořádku, směrováním provozu mimo instanci, která selhává, do instance, která je v pořádku.
  • Použití paměti, disku a dalších prostředků fyzického serveru je možné monitorovat, aby byl stav v pořádku.
  • Kontroly stavu můžou otestovat závislosti aplikace, jako jsou databáze a koncové body externí služby, a ověřit dostupnost a normální fungování.

Kontroly stavu se obvykle používají s externí službou monitorování nebo orchestrátorem kontejnerů ke kontrole stavu aplikace. Než do aplikace přidáte kontroly stavu, rozhodněte se, jaký monitorovací systém se má použít. Monitorovací systém určuje, jaké typy kontrol stavu se mají vytvořit a jak nakonfigurovat jejich koncové body.

Základní sonda stavu

U mnoha aplikací stačí základní konfigurace sondy stavu, která hlásí dostupnost aplikace pro zpracování požadavků (živé aktivity) ke zjištění stavu aplikace.

Základní konfigurace registruje služby kontroly stavu a volá Middleware kontroly stavu, aby reagoval na koncový bod adresy URL s odpovědí na stav. Ve výchozím nastavení nejsou žádné konkrétní kontroly stavu registrovány k testování žádné konkrétní závislosti nebo subsystému. Aplikace se považuje za v pořádku, pokud může reagovat na adresu URL koncového bodu stavu. Výchozí zapisovač odpovědí zapíše HealthStatus jako odpověď prostého textu klientovi. Je HealthStatusHealthStatus.Healthyto , HealthStatus.Degradednebo HealthStatus.Unhealthy.

Zaregistrujte služby kontroly stavu v adresáři AddHealthChecksProgram.cs. Vytvořte koncový bod kontroly stavu voláním MapHealthChecks.

Následující příklad vytvoří koncový bod kontroly stavu na /healthzadrese:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHealthChecks();

var app = builder.Build();

app.MapHealthChecks("/healthz");

app.Run();

DockeruHEALTHCHECK

Docker nabízí integrovanou HEALTHCHECK direktivu, která se dá použít ke kontrole stavu aplikace, která používá základní konfiguraci kontroly stavu:

HEALTHCHECK CMD curl --fail http://localhost:5000/healthz || exit

Předchozí příklad používá curl k vytvoření požadavku HTTP na koncový bod kontroly stavu na /healthzadrese . curl není součástí imagí kontejneru .NET Linux, ale dá se přidat instalací požadovaného balíčku do souboru Dockerfile. Kontejnery, které používají image založené na Alpine Linuxu, můžou místo zahrnutí wgetcurlpoužít .

Vytváření kontrol stavu

Kontroly stavu se vytvářejí implementací IHealthCheck rozhraní. Metoda CheckHealthAsync vrátí HealthCheckResult hodnotu, která označuje stav jako Healthy, Degradednebo Unhealthy. Výsledek se zapíše jako odpověď ve formátu prostého textu s konfigurovatelným stavovým kódem. Konfigurace je popsaná v části Možnosti kontroly stavu. HealthCheckResult může také vracet volitelné páry klíč-hodnota.

Následující příklad ukazuje rozložení kontroly stavu:

public class SampleHealthCheck : IHealthCheck
{
    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        var isHealthy = true;

        // ...

        if (isHealthy)
        {
            return Task.FromResult(
                HealthCheckResult.Healthy("A healthy result."));
        }

        return Task.FromResult(
            new HealthCheckResult(
                context.Registration.FailureStatus, "An unhealthy result."));
    }
}

Logika kontroly stavu je umístěna v CheckHealthAsync metodě. Předchozí příklad nastaví fiktivní proměnnou , isHealthyna true. Pokud je hodnota isHealthy nastavena na false, HealthCheckRegistration.FailureStatus stav se vrátí.

Pokud CheckHealthAsync při kontrole vyvolá výjimku, vrátí se nová HealthReportEntry hodnota s nastavenou HealthReportEntry.Status na FailureStatushodnotu . Tento stav je definován ( AddCheck viz část Služby kontroly stavu) a obsahuje vnitřní výjimku , která způsobila selhání kontroly. Je Description nastavená na zprávu výjimky.

Registrace služeb kontroly stavu

Pokud chcete zaregistrovat službu kontroly stavu, zavolejte AddCheck do Program.cs:

builder.Services.AddHealthChecks()
    .AddCheck<SampleHealthCheck>("Sample");

Přetížení AddCheck zobrazené v následujícím příkladu nastaví stav selhání (HealthStatus) tak, aby ohlásil, když kontrola stavu hlásí selhání. Pokud je stav selhání nastavený na null (výchozí), HealthStatus.Unhealthy je hlášeno. Toto přetížení je užitečný scénář pro autory knihoven, kde je stav selhání označený knihovnou vynucen aplikací, když dojde k selhání kontroly stavu, pokud implementace kontroly stavu dodržuje nastavení.

Značky lze použít k filtrování kontrol stavu. Značky jsou popsány v části Kontroly stavu filtru.

builder.Services.AddHealthChecks()
    .AddCheck<SampleHealthCheck>(
        "Sample",
        failureStatus: HealthStatus.Degraded,
        tags: new[] { "sample" });

AddCheck může také spustit funkci lambda. V následujícím příkladu vrátí kontrola stavu vždy výsledek, který je v pořádku:

builder.Services.AddHealthChecks()
    .AddCheck("Sample", () => HealthCheckResult.Healthy("A healthy result."));

Volání AddTypeActivatedCheck pro předání argumentů implementaci kontroly stavu V následujícím příkladu přijímá kontrola stavu aktivovaná typem celé číslo a řetězec v jeho konstruktoru:

public class SampleHealthCheckWithArgs : IHealthCheck
{
    private readonly int _arg1;
    private readonly string _arg2;

    public SampleHealthCheckWithArgs(int arg1, string arg2)
        => (_arg1, _arg2) = (arg1, arg2);

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        // ...

        return Task.FromResult(HealthCheckResult.Healthy("A healthy result."));
    }
}

Pokud chcete zaregistrovat předchozí kontrolu stavu, zavolejte AddTypeActivatedCheck celé číslo a řetězec předaný jako argumenty:

builder.Services.AddHealthChecks()
    .AddTypeActivatedCheck<SampleHealthCheckWithArgs>(
        "Sample",
        failureStatus: HealthStatus.Degraded,
        tags: new[] { "sample" },
        args: new object[] { 1, "Arg" });

Použití směrování kontrol stavu

MapHealthChecks Volání Program.cstvůrce koncových bodů pomocí adresy URL koncového bodu nebo relativní cesty:

app.MapHealthChecks("/healthz");

Vyžadovat hostitele

Volání RequireHost pro zadání jednoho nebo více povolených hostitelů pro koncový bod kontroly stavu Hostitelé by měli mít místo punycode kódování Unicode a můžou obsahovat port. Pokud kolekci nezadáte, přijme se žádný hostitel:

app.MapHealthChecks("/healthz")
    .RequireHost("www.contoso.com:5001");

Chcete-li omezit koncový bod kontroly stavu tak, aby reagoval pouze na konkrétním portu, zadejte port v volání RequireHost. Tento přístup se obvykle používá v prostředí kontejneru k zveřejnění portu pro monitorovací služby:

app.MapHealthChecks("/healthz")
    .RequireHost("*:5001");

Upozorňující

Rozhraní API, které závisí na hlavičce hostitele, například HttpRequest.Host a RequireHost, podléhají potenciálnímu falšování identity klienty.

Pokud chcete zabránit falšování identity hostitele a portu, použijte jeden z následujících přístupů:

Pokud chcete zabránit neoprávněným klientům v falšování identity portu, zavolejte RequireAuthorization:

app.MapHealthChecks("/healthz")
    .RequireHost("*:5001")
    .RequireAuthorization();

Další informace naleznete v tématu Porovnávání hostitelů v trasách s RequireHost.

Vyžadovat autorizaci

Volání RequireAuthorization pro spuštění autorizačního middlewaru na koncovém bodu žádosti o kontrolu stavu RequireAuthorization Přetížení přijímá jednu nebo více zásad autorizace. Pokud zásady nejsou zadané, použije se výchozí zásada autorizace:

app.MapHealthChecks("/healthz")
    .RequireAuthorization();

Povolení žádostí nepůvodního zdroje (CORS)

I když spouštění kontrol stavu ručně z prohlížeče není běžným scénářem, middleware CORS je možné povolit voláním RequireCors koncových bodů kontrol stavu. Přetížení RequireCors přijímá delegáta tvůrce zásad CORS (CorsPolicyBuilder) nebo název zásady. Další informace najdete v tématu Povolení žádostí mezi zdroji (CORS) v ASP.NET Core.

Možnosti kontroly stavu

HealthCheckOptions poskytnout příležitost přizpůsobit chování kontroly stavu:

Filtrování kontrol stavu

Ve výchozím nastavení spustí Middleware kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která vrátí logickou hodnotu možnosti Predicate .

Následující příklad filtruje kontroly stavu tak, aby se spustily pouze ty, které jsou označené jako spuštěné sample :

app.MapHealthChecks("/healthz", new HealthCheckOptions
{
    Predicate = healthCheck => healthCheck.Tags.Contains("sample")
});

Přizpůsobení stavového kódu HTTP

Slouží ResultStatusCodes k přizpůsobení mapování stavu na stavové kódy HTTP. Následující StatusCodes přiřazení jsou výchozí hodnoty používané middlewarem. Změňte hodnoty stavového kódu tak, aby splňovaly vaše požadavky:

app.MapHealthChecks("/healthz", new HealthCheckOptions
{
    ResultStatusCodes =
    {
        [HealthStatus.Healthy] = StatusCodes.Status200OK,
        [HealthStatus.Degraded] = StatusCodes.Status200OK,
        [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
    }
});

Potlačení hlaviček mezipaměti

AllowCachingResponses určuje, zda middleware kontroly stavu přidává hlavičky HTTP do odpovědi sondy, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je false hodnota (výchozí), middleware nastaví nebo přepíše Cache-ControlExpires, a Pragma hlavičky, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je truehodnota, middleware nezmění hlavičky mezipaměti odpovědi:

app.MapHealthChecks("/healthz", new HealthCheckOptions
{
    AllowCachingResponses = true
});

Přizpůsobení výstupu

Pokud chcete přizpůsobit výstup sestavy kontrol stavu, nastavte HealthCheckOptions.ResponseWriter vlastnost na delegáta, který zapisuje odpověď:

app.MapHealthChecks("/healthz", new HealthCheckOptions
{
    ResponseWriter = WriteResponse
});

Výchozí delegát zapíše minimální odpověď prostého textu s řetězcovou hodnotou HealthReport.Status. Následující vlastní delegát vypíše vlastní JSodpověď ON pomocí System.Text.Json:

private static Task WriteResponse(HttpContext context, HealthReport healthReport)
{
    context.Response.ContentType = "application/json; charset=utf-8";

    var options = new JsonWriterOptions { Indented = true };

    using var memoryStream = new MemoryStream();
    using (var jsonWriter = new Utf8JsonWriter(memoryStream, options))
    {
        jsonWriter.WriteStartObject();
        jsonWriter.WriteString("status", healthReport.Status.ToString());
        jsonWriter.WriteStartObject("results");

        foreach (var healthReportEntry in healthReport.Entries)
        {
            jsonWriter.WriteStartObject(healthReportEntry.Key);
            jsonWriter.WriteString("status",
                healthReportEntry.Value.Status.ToString());
            jsonWriter.WriteString("description",
                healthReportEntry.Value.Description);
            jsonWriter.WriteStartObject("data");

            foreach (var item in healthReportEntry.Value.Data)
            {
                jsonWriter.WritePropertyName(item.Key);

                JsonSerializer.Serialize(jsonWriter, item.Value,
                    item.Value?.GetType() ?? typeof(object));
            }

            jsonWriter.WriteEndObject();
            jsonWriter.WriteEndObject();
        }

        jsonWriter.WriteEndObject();
        jsonWriter.WriteEndObject();
    }

    return context.Response.WriteAsync(
        Encoding.UTF8.GetString(memoryStream.ToArray()));
}

Rozhraní API pro kontroly stavu neposkytuje integrovanou podporu složitých JSformátů on return, protože formát je specifický pro váš výběr monitorovacího systému. Podle potřeby upravte odpověď v předchozích příkladech. Další informace o JSpři serializaci pomocí System.Text.Json, naleznete v tématu Jak serializovat a deserializovat JSON v .NET.

Sonda databáze

Kontrola stavu může zadat databázový dotaz, který se má spustit jako logický test, který indikuje, jestli databáze normálně reaguje.

AspNetCore.Diagnostics.HealthChecks– knihovna kontroly stavu pro aplikace ASP.NET Core obsahuje kontrolu stavu, která se spouští v databázi SQL Serveru. AspNetCore.Diagnostics.HealthChecksSELECT 1 spustí dotaz na databázi, aby potvrdil, že připojení k databázi je v pořádku.

Upozorňující

Při kontrole připojení k databázi s dotazem zvolte dotaz, který se rychle vrátí. Přístup k dotazům riskuje přetížení databáze a snížení výkonu. Ve většině případů není spuštění testovacího dotazu nutné. Stačí pouze úspěšné připojení k databázi. Pokud zjistíte, že je nutné spustit dotaz, zvolte jednoduchý dotaz SELECT, například SELECT 1.

Pokud chcete použít tuto kontrolu stavu SQL Serveru, uveďte odkaz na AspNetCore.HealthChecks.SqlServer balíček NuGet. Následující příklad zaregistruje kontrolu stavu SQL Serveru:

var conStr = builder.Configuration.GetConnectionString("DefaultConnection");
if (string.IsNullOrEmpty(conStr))
{
    throw new InvalidOperationException(
                       "Could not find a connection string named 'DefaultConnection'.");
}
builder.Services.AddHealthChecks()
    .AddSqlServer(conStr);

Poznámka:

AspNetCore.Diagnostics.HealthChecks není udržována ani podporována společností Microsoft.

Sonda Entity Framework Core DbContext

Kontrola DbContext potvrzuje, že aplikace může komunikovat s databází nakonfigurovanou pro aplikaci EF CoreDbContext. Kontrola je podporovaná DbContext v aplikacích, které:

AddDbContextCheckzaregistruje kontrolu stavu pro DbContext Metoda DbContext je zadána jako TContext. K dispozici je přetížení ke konfiguraci stavu selhání, značek a vlastního testovacího dotazu.

Standardně:

  • EF CoreCanConnectAsync Volání DbContextHealthCheck metody. Můžete přizpůsobit, jakou operaci se spustí při kontrole stavu pomocí AddDbContextCheck přetížení metod.
  • Název kontroly stavu je název TContext typu.

Následující příklad zaregistruje a DbContext přidružené DbContextHealthCheck:

builder.Services.AddDbContext<SampleDbContext>(options =>
    options.UseSqlServer(
        builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddHealthChecks()
    .AddDbContextCheck<SampleDbContext>();

Samostatné testy připravenosti a aktivity

V některých scénářích hostování se k rozlišení dvou stavů aplikace používá pár kontrol stavu:

  • Připravenost označuje, jestli aplikace běží normálně, ale není připravená přijímat žádosti.
  • Liveness označuje, jestli se aplikace chybově ukončila a musí se restartovat.

Představte si následující příklad: Aplikace musí stáhnout velký konfigurační soubor, než bude připraven zpracovávat požadavky. Nechceme, aby se aplikace restartovala, pokud se počáteční stahování nezdaří, protože aplikace může několikrát zkusit stáhnout soubor znovu. K popisu aktivity procesu používáme sondu živé aktivity, nespustíme žádné další kontroly. Chceme také zabránit tomu, aby se žádosti odesílaly do aplikace před úspěšným stažením konfiguračního souboru. Sondu připravenosti použijeme k označení stavu "nepřipraveno", dokud stahování nebude úspěšné a aplikace bude připravená přijímat žádosti.

Následující úloha na pozadí simuluje proces spuštění, který trvá přibližně 15 sekund. Po dokončení nastaví úloha StartupHealthCheck.StartupCompleted vlastnost na true:

public class StartupBackgroundService : BackgroundService
{
    private readonly StartupHealthCheck _healthCheck;

    public StartupBackgroundService(StartupHealthCheck healthCheck)
        => _healthCheck = healthCheck;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        // Simulate the effect of a long-running task.
        await Task.Delay(TimeSpan.FromSeconds(15), stoppingToken);

        _healthCheck.StartupCompleted = true;
    }
}

StartupHealthCheck Hlásí dokončení dlouhotrvající spouštěcí úlohy a zveřejňuje StartupCompleted vlastnost, která se nastaví službou na pozadí:

public class StartupHealthCheck : IHealthCheck
{
    private volatile bool _isReady;

    public bool StartupCompleted
    {
        get => _isReady;
        set => _isReady = value;
    }

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        if (StartupCompleted)
        {
            return Task.FromResult(HealthCheckResult.Healthy("The startup task has completed."));
        }

        return Task.FromResult(HealthCheckResult.Unhealthy("That startup task is still running."));
    }
}

Kontrola stavu je zaregistrovaná AddCheckProgram.cs společně s hostovanými službami. Vzhledem k tomu, že hostovaná služba musí nastavit vlastnost kontroly stavu, je kontrola stavu také zaregistrována v kontejneru služby jako singleton:

builder.Services.AddHostedService<StartupBackgroundService>();
builder.Services.AddSingleton<StartupHealthCheck>();

builder.Services.AddHealthChecks()
    .AddCheck<StartupHealthCheck>(
        "Startup",
        tags: new[] { "ready" });

Pokud chcete vytvořit dva různé koncové body kontroly stavu, volejte MapHealthChecks dvakrát:

app.MapHealthChecks("/healthz/ready", new HealthCheckOptions
{
    Predicate = healthCheck => healthCheck.Tags.Contains("ready")
});

app.MapHealthChecks("/healthz/live", new HealthCheckOptions
{
    Predicate = _ => false
});

Předchozí příklad vytvoří následující koncové body kontroly stavu:

  • /healthz/ready pro kontrolu připravenosti. Kontrola připravenosti filtruje kontroly stavu na ty, které jsou označené ready.
  • /healthz/live pro kontrolu živého života. Kontrola aktivity filtruje všechny kontroly stavu vrácením false delegáta HealthCheckOptions.Predicate . Další informace o filtrování kontrol stavu najdete v tématu Filtrování kontrol stavu v tomto článku.

Před dokončením /healthz/ready spouštěcí úlohy koncový bod hlásí Unhealthy stav. Po dokončení spouštěcí úlohy tento koncový bod hlásí Healthy stav. Koncový /healthz/live bod vyloučí všechny kontroly a hlásí Healthy stav všech volání.

Příklad Kubernetes

Použití samostatných kontrol připravenosti a aktivity je užitečné v prostředí, jako je Kubernetes. V Kubernetes může být aplikace nutná ke spouštění časově náročných spouštěcích prací před přijetím požadavků, jako je například test dostupnosti podkladové databáze. Použití samostatných kontrol umožňuje orchestrátoru rozlišit, jestli aplikace funguje, ale ještě není připravená nebo jestli se aplikaci nepodařilo spustit. Další informace o testech připravenosti a aktivity v Kubernetes najdete v dokumentaci ke konfiguraci testů živé aktivity a připravenosti v Kubernetes.

Následující příklad ukazuje konfiguraci sondy připravenosti Kubernetes:

spec:
  template:
  spec:
    readinessProbe:
      # an http probe
      httpGet:
        path: /healthz/ready
        port: 80
      # length of time to wait for a pod to initialize
      # after pod startup, before applying health checking
      initialDelaySeconds: 30
      timeoutSeconds: 1
    ports:
      - containerPort: 80

Distribuce knihovny kontroly stavu

Distribuce kontroly stavu jako knihovny:

  1. Napište kontrolu stavu, která implementuje IHealthCheck rozhraní jako samostatnou třídu. Třída se může spoléhat na injektáž závislostí (DI), aktivaci typu a pojmenované možnosti pro přístup ke konfiguračním datům.

  2. Napište metodu rozšíření s parametry, které spotřebová aplikace volá ve své Program.cs metodě. Podívejte se na následující příklad kontroly stavu, která přijímá arg1 parametry konstruktoru a arg2 jako parametry:

    public SampleHealthCheckWithArgs(int arg1, string arg2)
        => (_arg1, _arg2) = (arg1, arg2);
    

    Předchozí podpis označuje, že kontrola stavu vyžaduje vlastní data ke zpracování logiky sondy kontroly stavu. Data se poskytují delegátu použitému k vytvoření instance kontroly stavu při registraci kontroly stavu v metodě rozšíření. V následujícím příkladu volající určuje:

    • arg1: Celočíselná datová hodnota pro kontrolu stavu.
    • arg2: Řetězcový argument pro kontrolu stavu.
    • name: Volitelný název kontroly stavu. Pokud nullse použije výchozí hodnota.
    • failureStatus: Nepovinný údaj HealthStatus, který je hlášen pro stav selhání. Pokud nullse použije , HealthStatus.Unhealthy použije se.
    • tags: Volitelná IEnumerable<string> kolekce značek.
    public static class SampleHealthCheckBuilderExtensions
    {
        private const string DefaultName = "Sample";
    
        public static IHealthChecksBuilder AddSampleHealthCheck(
            this IHealthChecksBuilder healthChecksBuilder,
            int arg1,
            string arg2,
            string? name = null,
            HealthStatus? failureStatus = null,
            IEnumerable<string>? tags = default)
        {
            return healthChecksBuilder.Add(
                new HealthCheckRegistration(
                    name ?? DefaultName,
                    _ => new SampleHealthCheckWithArgs(arg1, arg2),
                    failureStatus,
                    tags));
        }
    }
    

Kontrola stavu – Vydavatel

IHealthCheckPublisher Po přidání do kontejneru služby systém kontroly stavu pravidelně provádí kontroly stavu a volání PublishAsync s výsledkem. Tento proces je užitečný ve scénáři systému monitorování stavu založeného na nabízených oznámeních, který očekává, že každý proces bude pravidelně volat monitorovací systém, aby zjistil stav.

HealthCheckPublisherOptions umožňuje nastavit:

  • Delay: Počáteční prodleva použitá po spuštění aplikace před spuštěním IHealthCheckPublisher instancí. Zpoždění se použije jednou při spuštění a nevztahuje se na pozdější iterace. Výchozí hodnota je pět sekund.
  • Period: Období IHealthCheckPublisher provádění. Výchozí hodnota je 30 sekund.
  • Predicate: Pokud Predicate je null (výchozí), spustí služba vydavatele kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která filtruje sadu kontrol. Predikát se vyhodnocuje každé období.
  • Timeout: Časový limit pro provádění kontrol stavu pro všechny IHealthCheckPublisher instance. Slouží InfiniteTimeSpan ke spuštění bez časového limitu. Výchozí hodnota je 30 sekund.

Následující příklad ukazuje rozložení vydavatele stavu:

public class SampleHealthCheckPublisher : IHealthCheckPublisher
{
    public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
    {
        if (report.Status == HealthStatus.Healthy)
        {
            // ...
        }
        else
        {
            // ...
        }

        return Task.CompletedTask;
    }
}

Třída HealthCheckPublisherOptions poskytuje vlastnosti pro konfiguraci chování vydavatele kontroly stavu.

Následující příklad zaregistruje vydavatele kontroly stavu jako singleton a nakonfiguruje HealthCheckPublisherOptions:

builder.Services.Configure<HealthCheckPublisherOptions>(options =>
{
    options.Delay = TimeSpan.FromSeconds(2);
    options.Predicate = healthCheck => healthCheck.Tags.Contains("sample");
});

builder.Services.AddSingleton<IHealthCheckPublisher, SampleHealthCheckPublisher>();

AspNetCore.Diagnostics.HealthChecks:

  • Zahrnuje vydavatele pro několik systémů, včetně aplikačních Přehledy.
  • Společnost Microsoft není udržována ani podporována.

Jednotlivé kontroly stavu

Delay a Period lze je nastavit pro každou HealthCheckRegistration jednotlivou. To je užitečné, když chcete spustit některé kontroly stavu s jinou rychlostí, než je doba nastavená v HealthCheckPublisherOptions.

Následující kód nastaví Delay a Period pro SampleHealthCheck1:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHealthChecks()
   .Add(new HealthCheckRegistration(
       name: "SampleHealthCheck1",
       instance: new SampleHealthCheck(),
       failureStatus: null,
       tags: null,
       timeout: default)
   {
       Delay = TimeSpan.FromSeconds(40),
       Period = TimeSpan.FromSeconds(30)
   });

var app = builder.Build();

app.MapHealthChecks("/healthz");

app.Run();

Injektáž závislostí a kontroly stavu

Injektáž závislostí je možné použít ke spotřebování instance konkrétní Type instance uvnitř třídy kontroly stavu. Injektáž závislostí může být užitečná pro vložení možností nebo globální konfigurace do kontroly stavu. Použití injektáže závislostí není běžným scénářem konfigurace kontrol stavu. Každá kontrola stavu je obvykle zcela specifická pro skutečný test a je nakonfigurovaná pomocí IHealthChecksBuilder rozšiřujících metod.

Následující příklad ukazuje ukázkovou kontrolu stavu, která načte objekt konfigurace prostřednictvím injektáže závislostí:

public class SampleHealthCheckWithDI : IHealthCheck
{
    private readonly SampleHealthCheckWithDiConfig _config;

    public SampleHealthCheckWithDI(SampleHealthCheckWithDiConfig config)
        => _config = config;

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        var isHealthy = true;

        // use _config ...

        if (isHealthy)
        {
            return Task.FromResult(
                HealthCheckResult.Healthy("A healthy result."));
        }

        return Task.FromResult(
            new HealthCheckResult(
                context.Registration.FailureStatus, "An unhealthy result."));
    }
}

Do SampleHealthCheckWithDiConfig kontejneru služby je potřeba přidat kontrolu stavu:

builder.Services.AddSingleton<SampleHealthCheckWithDiConfig>(new SampleHealthCheckWithDiConfig
{
    BaseUriToCheck = new Uri("https://sample.contoso.com/api/")
});
builder.Services.AddHealthChecks()
    .AddCheck<SampleHealthCheckWithDI>(
        "With Dependency Injection",
        tags: new[] { "inject" });

UseHealthChecks vs. MapHealthChecks

Existují dva způsoby zpřístupnění kontrol stavu volajícím:

  • UseHealthChecks zaregistruje middleware pro zpracování žádostí o kontroly stavu v kanálu middlewaru.
  • MapHealthChecks zaregistruje koncový bod kontroly stavu. Koncový bod se porovná a spustí spolu s dalšími koncovými body v aplikaci.

Výhodou použití MapHealthChecks oproti UseHealthChecks tomu je možnost používat middleware s podporou koncových bodů, jako je autorizace, a mít větší jemně odstupňovanou kontrolu nad odpovídajícími zásadami. Hlavní výhodou použití UseHealthChecks je MapHealthChecks řízení přesně toho, kde se kontroly stavu spouští v kanálu middlewaru.

UseHealthChecks:

  • Ukončí kanál, když požadavek odpovídá koncovému bodu kontroly stavu. Zkratování je často žádoucí, protože zabraňuje zbytečné práci, jako je protokolování a další middleware.
  • Primárně se používá ke konfiguraci middlewaru kontroly stavu v kanálu.
  • Může odpovídat jakékoli cestě na portu s nebo prázdným nullPathString. Umožňuje provést kontrolu stavu u všech požadavků provedených na zadaném portu.
  • Zdrojový kód

MapHealthChecks Umožňuje:

  • Ukončení kanálu, když požadavek odpovídá koncovému bodu kontroly stavu voláním ShortCircuit. Například app.MapHealthChecks("/healthz").ShortCircuit();. Další informace najdete v tématu Middleware s krátkým okruhem po směrování.
  • Mapování konkrétních tras nebo koncových bodů pro kontroly stavu
  • Přizpůsobení adresy URL nebo cesty, kde je koncový bod kontroly stavu přístupný.
  • Mapování několika koncových bodů kontroly stavu s různými trasami nebo konfiguracemi Podpora více koncových bodů:
    • Umožňuje samostatné koncové body pro různé typy kontrol stavu nebo součástí.
    • Používá se k rozlišení různých aspektů stavu aplikace nebo použití konkrétních konfigurací na podmnožinu kontrol stavu.
  • Zdrojový kód

Další materiály

Poznámka:

Tento článek byl částečně vytvořen pomocí umělé inteligence. Před zveřejněním autor obsah zkontroloval a podle potřeby upravil. Viz Naše zásady pro používání obsahu generovaného AI v Microsoft Learn.

ASP.NET Core nabízí middlewarové kontroly stavu a knihovny pro vytváření sestav stavu komponent infrastruktury aplikací.

Kontroly stavu jsou vystaveny aplikací jako koncové body HTTP. Koncové body kontroly stavu je možné nakonfigurovat pro různé scénáře monitorování v reálném čase:

  • Sondy stavu můžou používat orchestrátory kontejnerů a nástroje pro vyrovnávání zatížení ke kontrole stavu aplikace. Orchestrátor kontejnerů může například reagovat na neúspěšnou kontrolu stavu zastavením postupného nasazení nebo restartováním kontejneru. Nástroj pro vyrovnávání zatížení může reagovat na aplikaci, která není v pořádku, směrováním provozu mimo instanci, která selhává, do instance, která je v pořádku.
  • Použití paměti, disku a dalších prostředků fyzického serveru je možné monitorovat, aby byl stav v pořádku.
  • Kontroly stavu můžou otestovat závislosti aplikace, jako jsou databáze a koncové body externí služby, a ověřit dostupnost a normální fungování.

Zobrazení nebo stažení ukázkového kódu (postup stažení)

Ukázková aplikace obsahuje příklady scénářů popsaných v tomto článku. Pokud chcete spustit ukázkovou aplikaci pro daný scénář, použijte příkaz dotnet run ze složky projektu v příkazovém prostředí. Podrobnosti o používání ukázkové aplikace najdete v souboru ukázkové aplikace README.md a popisech scénářů v tomto článku.

Požadavky

Kontroly stavu se obvykle používají s externí službou monitorování nebo orchestrátorem kontejnerů ke kontrole stavu aplikace. Než do aplikace přidáte kontroly stavu, rozhodněte se, jaký monitorovací systém se má použít. Monitorovací systém určuje, jaké typy kontrol stavu se mají vytvořit a jak nakonfigurovat jejich koncové body.

Na Microsoft.AspNetCore.Diagnostics.HealthChecks balíček se implicitně odkazuje pro aplikace ASP.NET Core. Pokud chcete spouštět kontroly stavu pomocí Entity Framework Core, přidejte odkaz na Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore balíček.

Ukázková aplikace poskytuje spouštěcí kód, který demonstruje kontroly stavu pro několik scénářů. Scénář sondy databáze kontroluje stav připojení k databázi pomocí AspNetCore.Diagnostics.HealthChecks. Scénář sondy DbContext kontroluje databázi pomocí .EF CoreDbContext Pokud chcete prozkoumat databázové scénáře, ukázková aplikace:

Poznámka:

AspNetCore.Diagnostics.HealthChecks není udržována ani podporována společností Microsoft.

Další scénář kontroly stavu ukazuje, jak filtrovat kontroly stavu na port pro správu. Ukázková aplikace vyžaduje, Properties/launchSettings.json abyste vytvořili soubor, který obsahuje adresu URL pro správu a port pro správu. Další informace najdete v části Filtrovat podle portu .

Základní sonda stavu

U mnoha aplikací stačí základní konfigurace sondy stavu, která hlásí dostupnost aplikace pro zpracování požadavků (živé aktivity) ke zjištění stavu aplikace.

Základní konfigurace registruje služby kontroly stavu a volá Middleware kontroly stavu, aby reagoval na koncový bod adresy URL s odpovědí na stav. Ve výchozím nastavení nejsou žádné konkrétní kontroly stavu registrovány k testování žádné konkrétní závislosti nebo subsystému. Aplikace se považuje za v pořádku, pokud může reagovat na adresu URL koncového bodu stavu. Výchozí zapisovač odpovědí zapíše stav (HealthStatus) jako odpověď ve formátu prostého textu zpět klientovi, který označuje HealthStatus.Healthyhodnotu , HealthStatus.Degradednebo HealthStatus.Unhealthy stav.

Zaregistrujte služby kontroly stavu v adresáři AddHealthChecksStartup.ConfigureServices. Vytvořte koncový bod kontroly stavu voláním MapHealthChecksStartup.Configure.

V ukázkové aplikaci se koncový bod kontroly stavu vytvoří na adrese /health (BasicStartup.cs):

public class BasicStartup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHealthChecks();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapHealthChecks("/health");
        });
    }
}

Pokud chcete spustit základní scénář konfigurace pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:

dotnet run --scenario basic

Příklad Dockeru

Docker nabízí integrovanou HEALTHCHECK direktivu, která se dá použít ke kontrole stavu aplikace, která používá základní konfiguraci kontroly stavu:

HEALTHCHECK CMD curl --fail http://localhost:5000/health || exit

Vytváření kontrol stavu

Kontroly stavu se vytvářejí implementací IHealthCheck rozhraní. Metoda CheckHealthAsync vrátí HealthCheckResult hodnotu, která označuje stav jako Healthy, Degradednebo Unhealthy. Výsledek se zapíše jako odpověď prostého textu s konfigurovatelným stavovým kódem (konfigurace je popsaná v části Možnosti kontroly stavu). HealthCheckResult může také vracet volitelné páry klíč-hodnota.

Následující ExampleHealthCheck třída ukazuje rozložení kontroly stavu. Logika kontroly stavu je umístěna CheckHealthAsync v metodě. Následující příklad nastaví fiktivní proměnnou , healthCheckResultHealthyna true. Pokud je hodnota healthCheckResultHealthy nastavena na false, HealthCheckRegistration.FailureStatus stav se vrátí.

public class ExampleHealthCheck : IHealthCheck
{
    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        var healthCheckResultHealthy = true;

        if (healthCheckResultHealthy)
        {
            return Task.FromResult(
                HealthCheckResult.Healthy("A healthy result."));
        }

        return Task.FromResult(
            new HealthCheckResult(context.Registration.FailureStatus, 
            "An unhealthy result."));
    }
}

Pokud CheckHealthAsync při kontrole vyvolá výjimku, vrátí se nová HealthReportEntry položka s HealthReportEntry.Status nastavenou na hodnotu FailureStatusdefinovanou AddCheck (viz část Služby kontroly stavu registru) a obsahuje vnitřní výjimku , která původně způsobila chybu kontroly. Je Description nastavená na zprávu výjimky.

Registrace služeb kontroly stavu

Typ ExampleHealthCheck se přidá ke službám kontroly stavu s následujícími položkami AddCheckStartup.ConfigureServices:

services.AddHealthChecks()
    .AddCheck<ExampleHealthCheck>("example_health_check");

Přetížení AddCheck zobrazené v následujícím příkladu nastaví stav selhání (HealthStatus) tak, aby ohlásil, když kontrola stavu hlásí selhání. Pokud je stav selhání nastavený na null (výchozí), HealthStatus.Unhealthy je hlášeno. Toto přetížení je užitečný scénář pro autory knihoven, kde je stav selhání označený knihovnou vynucen aplikací, když dojde k selhání kontroly stavu, pokud implementace kontroly stavu dodržuje nastavení.

Značky lze použít k filtrování kontrol stavu (popsáno dále v části Kontroly stavu filtru).

services.AddHealthChecks()
    .AddCheck<ExampleHealthCheck>(
        "example_health_check",
        failureStatus: HealthStatus.Degraded,
        tags: new[] { "example" });

AddCheck může také spustit funkci lambda. V následujícím příkladu je název kontroly stavu zadán jako Example a kontrola vždy vrátí stav v pořádku:

services.AddHealthChecks()
    .AddCheck("Example", () =>
        HealthCheckResult.Healthy("Example is OK!"), tags: new[] { "example" });

Volání AddTypeActivatedCheck pro předání argumentů implementaci kontroly stavu V následujícím příkladu TestHealthCheckWithArgs přijímá celé číslo a řetězec pro použití, pokud CheckHealthAsync je volán:

private class TestHealthCheckWithArgs : IHealthCheck
{
    public TestHealthCheckWithArgs(int i, string s)
    {
        I = i;
        S = s;
    }

    public int I { get; set; }

    public string S { get; set; }

    public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, 
        CancellationToken cancellationToken = default)
    {
        ...
    }
}

TestHealthCheckWithArgs je registrován voláním AddTypeActivatedCheck celého čísla a řetězce předaného implementaci:

services.AddHealthChecks()
    .AddTypeActivatedCheck<TestHealthCheckWithArgs>(
        "test", 
        failureStatus: HealthStatus.Degraded, 
        tags: new[] { "example" }, 
        args: new object[] { 5, "string" });

Použití směrování kontrol stavu

MapHealthChecks Volání Startup.Configuretvůrce koncových bodů pomocí adresy URL koncového bodu nebo relativní cesty:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health");
});

Vyžadovat hostitele

Volání RequireHost pro zadání jednoho nebo více povolených hostitelů pro koncový bod kontroly stavu Hostitelé by měli mít místo punycode kódování Unicode a můžou obsahovat port. Pokud kolekci nezadáte, přijme se žádný hostitel.

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health").RequireHost("www.contoso.com:5001");
});

Další informace najdete v části Filtrovat podle portu .

Vyžadovat autorizaci

Volání RequireAuthorization pro spuštění autorizačního middlewaru na koncovém bodu žádosti o kontrolu stavu RequireAuthorization Přetížení přijímá jednu nebo více zásad autorizace. Pokud zásady nejsou zadané, použijí se výchozí zásady autorizace.

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health").RequireAuthorization();
});

Povolení žádostí nepůvodního zdroje (CORS)

I když spouštění kontrol stavu ručně z prohlížeče není běžným scénářem použití, middleware CORS je možné povolit voláním RequireCors koncových bodů kontrol stavu. RequireCors Přetížení přijímá delegátaCorsPolicyBuilder () nebo název zásady CORS. Pokud zásady nejsou zadané, použije se výchozí zásada CORS. Další informace najdete v tématu Povolení žádostí mezi zdroji (CORS) v ASP.NET Core.

Možnosti kontroly stavu

HealthCheckOptions poskytnout příležitost přizpůsobit chování kontroly stavu:

Filtrování kontrol stavu

Ve výchozím nastavení spustí Middleware kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která vrátí logickou hodnotu možnosti Predicate . V následujícím příkladu Bar se kontrola stavu vyfiltruje podle značky (bar_tag) v podmíněném příkazu funkce, kde true se vrátí pouze v případě, že se vlastnost kontroly Tags stavu shoduje foo_tag nebo baz_tag:

V Startup.ConfigureServices:

services.AddHealthChecks()
    .AddCheck("Foo", () =>
        HealthCheckResult.Healthy("Foo is OK!"), tags: new[] { "foo_tag" })
    .AddCheck("Bar", () =>
        HealthCheckResult.Unhealthy("Bar is unhealthy!"), tags: new[] { "bar_tag" })
    .AddCheck("Baz", () =>
        HealthCheckResult.Healthy("Baz is OK!"), tags: new[] { "baz_tag" });

Vyfiltruje Startup.ConfigurePredicate kontrolu stavu panelu. Pouze Foo a Baz provést:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health", new HealthCheckOptions()
    {
        Predicate = (check) => check.Tags.Contains("foo_tag") ||
            check.Tags.Contains("baz_tag")
    });
});

Přizpůsobení stavového kódu HTTP

Slouží ResultStatusCodes k přizpůsobení mapování stavu na stavové kódy HTTP. Následující StatusCodes přiřazení jsou výchozí hodnoty používané middlewarem. Změňte hodnoty stavového kódu tak, aby splňovaly vaše požadavky.

V Startup.Configure:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health", new HealthCheckOptions()
    {
        ResultStatusCodes =
        {
            [HealthStatus.Healthy] = StatusCodes.Status200OK,
            [HealthStatus.Degraded] = StatusCodes.Status200OK,
            [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
        }
    });
});

Potlačení hlaviček mezipaměti

AllowCachingResponses určuje, zda middleware kontroly stavu přidává hlavičky HTTP do odpovědi sondy, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je false hodnota (výchozí), middleware nastaví nebo přepíše Cache-ControlExpires, a Pragma hlavičky, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je truehodnota, middleware neupraví hlavičky mezipaměti odpovědi.

V Startup.Configure:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health", new HealthCheckOptions()
    {
        AllowCachingResponses = true
    });
});

Přizpůsobení výstupu

Nastavte Startup.Configuremožnost HealthCheckOptions.ResponseWriter delegáta pro zápis odpovědi:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health", new HealthCheckOptions()
    {
        ResponseWriter = WriteResponse
    });
});

Výchozí delegát zapíše minimální odpověď prostého textu s řetězcovou hodnotou HealthReport.Status. Následující vlastní delegáti vypíše vlastní JSodpověď ON.

První příklad z ukázkové aplikace ukazuje, jak používat System.Text.Json:

private static Task WriteResponse(HttpContext context, HealthReport result)
{
    context.Response.ContentType = "application/json; charset=utf-8";

    var options = new JsonWriterOptions
    {
        Indented = true
    };

    using (var stream = new MemoryStream())
    {
        using (var writer = new Utf8JsonWriter(stream, options))
        {
            writer.WriteStartObject();
            writer.WriteString("status", result.Status.ToString());
            writer.WriteStartObject("results");
            foreach (var entry in result.Entries)
            {
                writer.WriteStartObject(entry.Key);
                writer.WriteString("status", entry.Value.Status.ToString());
                writer.WriteString("description", entry.Value.Description);
                writer.WriteStartObject("data");
                foreach (var item in entry.Value.Data)
                {
                    writer.WritePropertyName(item.Key);
                    JsonSerializer.Serialize(
                        writer, item.Value, item.Value?.GetType() ??
                        typeof(object));
                }
                writer.WriteEndObject();
                writer.WriteEndObject();
            }
            writer.WriteEndObject();
            writer.WriteEndObject();
        }

        var json = Encoding.UTF8.GetString(stream.ToArray());

        return context.Response.WriteAsync(json);
    }
}

Druhý příklad ukazuje, jak použít Newtonsoft.Json:

private static Task WriteResponse(HttpContext context, HealthReport result)
{
    context.Response.ContentType = "application/json";

    var json = new JObject(
        new JProperty("status", result.Status.ToString()),
        new JProperty("results", new JObject(result.Entries.Select(pair =>
            new JProperty(pair.Key, new JObject(
                new JProperty("status", pair.Value.Status.ToString()),
                new JProperty("description", pair.Value.Description),
                new JProperty("data", new JObject(pair.Value.Data.Select(
                    p => new JProperty(p.Key, p.Value))))))))));

    return context.Response.WriteAsync(
        json.ToString(Formatting.Indented));
}

V ukázkové aplikaci zakomentujte direktivu preprocesoruSYSTEM_TEXT_JSON, aby bylo možné povolit Newtonsoft.Json verzi WriteResponse.CustomWriterStartup.cs

Rozhraní API pro kontroly stavu neposkytuje integrovanou podporu složitých JSformátů on return, protože formát je specifický pro váš výběr monitorovacího systému. Podle potřeby upravte odpověď v předchozích příkladech. Další informace o JSpři serializaci pomocí System.Text.Json, naleznete v tématu Jak serializovat a deserializovat JSON v .NET.

Sonda databáze

Kontrola stavu může zadat databázový dotaz, který se má spustit jako logický test, který indikuje, jestli databáze normálně reaguje.

Ukázková aplikace používá AspNetCore.Diagnostics.HealthChecksknihovnu kontroly stavu pro aplikace ASP.NET Core ke spuštění kontroly stavu v databázi SQL Serveru. AspNetCore.Diagnostics.HealthChecksSELECT 1 spustí dotaz na databázi, aby potvrdil, že připojení k databázi je v pořádku.

Upozorňující

Při kontrole připojení k databázi s dotazem zvolte dotaz, který se rychle vrátí. Přístup k dotazům riskuje přetížení databáze a snížení výkonu. Ve většině případů není spuštění testovacího dotazu nutné. Stačí pouze úspěšné připojení k databázi. Pokud zjistíte, že je nutné spustit dotaz, zvolte jednoduchý dotaz SELECT, například SELECT 1.

Zahrnout odkaz na AspNetCore.HealthChecks.SqlServerbalíček .

Do souboru ukázkové aplikace zadejte platný připojovací řetězec appsettings.json databáze. Aplikace používá databázi SQL Serveru s názvem HealthCheckSample:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=HealthCheckSample;Trusted_Connection=True;MultipleActiveResultSets=true;ConnectRetryCount=0"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    },
    "Console": {
      "IncludeScopes": "true"
    }
  },
  "AllowedHosts": "*"
}

Zaregistrujte služby kontroly stavu v adresáři AddHealthChecksStartup.ConfigureServices. Ukázková aplikace volá metodu AddSqlServer s připojovací řetězec databáze (DbHealthStartup.cs):

services.AddHealthChecks()
    .AddSqlServer(Configuration["ConnectionStrings:DefaultConnection"]);

Koncový bod kontroly stavu se vytvoří voláním MapHealthChecksStartup.Configure:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health");
}

Pokud chcete spustit scénář sondy databáze pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:

dotnet run --scenario db

Poznámka:

AspNetCore.Diagnostics.HealthChecks není udržována ani podporována společností Microsoft.

Sonda Entity Framework Core DbContext

Kontrola DbContext potvrzuje, že aplikace může komunikovat s databází nakonfigurovanou pro aplikaci EF CoreDbContext. Kontrola je podporovaná DbContext v aplikacích, které:

AddDbContextCheck<TContext>zaregistruje kontrolu stavu pro DbContext Tato DbContext metoda je zadána TContext jako metoda. K dispozici je přetížení ke konfiguraci stavu selhání, značek a vlastního testovacího dotazu.

Standardně:

  • EF CoreCanConnectAsync Volání DbContextHealthCheck metody. Můžete přizpůsobit, jakou operaci se spustí při kontrole stavu pomocí AddDbContextCheck přetížení metod.
  • Název kontroly stavu je název TContext typu.

V ukázkové aplikaci AppDbContext se poskytuje AddDbContextCheck a zaregistruje jako služba v Startup.ConfigureServices :DbContextHealthStartup.cs

services.AddHealthChecks()
    .AddDbContextCheck<AppDbContext>();

services.AddDbContext<AppDbContext>(options =>
{
    options.UseSqlServer(
        Configuration["ConnectionStrings:DefaultConnection"]);
});

Koncový bod kontroly stavu se vytvoří voláním MapHealthChecksStartup.Configure:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health");
}

Pokud chcete spustit scénář sondy DbContext pomocí ukázkové aplikace, ověřte, že databáze zadaná připojovací řetězec v instanci SQL Serveru neexistuje. Pokud databáze existuje, odstraňte ji.

V příkazovém prostředí spusťte následující příkaz ze složky projektu:

dotnet run --scenario dbcontext

Po spuštění aplikace zkontrolujte stav provedením požadavku na /health koncový bod v prohlížeči. Databáze a AppDbContext neexistuje, takže aplikace poskytuje následující odpověď:

Unhealthy

Aktivujte ukázkovou aplikaci a vytvořte databázi. Vytvořte žádost na /createdatabase. Aplikace reaguje:

Creating the database...
Done!
Navigate to /health to see the health status.

Vytvořte požadavek na /health koncový bod. Databáze a kontext existují, takže aplikace reaguje:

Healthy

Aktivujte ukázkovou aplikaci, aby se databáze odstranila. Vytvořte žádost na /deletedatabase. Aplikace reaguje:

Deleting the database...
Done!
Navigate to /health to see the health status.

Vytvořte požadavek na /health koncový bod. Aplikace poskytuje odpověď, která není v pořádku:

Unhealthy

Samostatné testy připravenosti a aktivity

V některých scénářích hostování se k rozlišení dvou stavů aplikace používá pár kontrol stavu:

  • Připravenost označuje, jestli aplikace běží normálně, ale není připravená přijímat žádosti.
  • Liveness označuje, jestli se aplikace chybově ukončila a musí se restartovat.

Představte si následující příklad: Aplikace musí stáhnout velký konfigurační soubor, než bude připraven zpracovávat požadavky. Nechceme, aby se aplikace restartovala, pokud se počáteční stahování nezdaří, protože aplikace může několikrát zkusit stáhnout soubor znovu. K popisu aktivity procesu používáme sondu živé aktivity, nespustíme žádné další kontroly. Chceme také zabránit tomu, aby se žádosti odesílaly do aplikace před úspěšným stažením konfiguračního souboru. Sondu připravenosti použijeme k označení stavu "nepřipraveno", dokud stahování nebude úspěšné a aplikace bude připravená přijímat žádosti.

Ukázková aplikace obsahuje kontrolu stavu, která hlásí dokončení dlouhotrvající spouštěcí úlohy v hostované službě. Zpřístupňuje StartupHostedServiceHealthCheck vlastnost, StartupTaskCompletedkterou hostovaná služba může nastavit na true po dokončení dlouhotrvající úlohy (StartupHostedServiceHealthCheck.cs):

public class StartupHostedServiceHealthCheck : IHealthCheck
{
    private volatile bool _startupTaskCompleted = false;

    public string Name => "slow_dependency_check";

    public bool StartupTaskCompleted
    {
        get => _startupTaskCompleted;
        set => _startupTaskCompleted = value;
    }

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        if (StartupTaskCompleted)
        {
            return Task.FromResult(
                HealthCheckResult.Healthy("The startup task is finished."));
        }

        return Task.FromResult(
            HealthCheckResult.Unhealthy("The startup task is still running."));
    }
}

Dlouhotrvající úloha na pozadí je spuštěna hostované službou (Services/StartupHostedService). Na závěr úkolu StartupHostedServiceHealthCheck.StartupTaskCompleted je nastaveno:true

public class StartupHostedService : IHostedService, IDisposable
{
    private readonly int _delaySeconds = 15;
    private readonly ILogger _logger;
    private readonly StartupHostedServiceHealthCheck _startupHostedServiceHealthCheck;

    public StartupHostedService(ILogger<StartupHostedService> logger,
        StartupHostedServiceHealthCheck startupHostedServiceHealthCheck)
    {
        _logger = logger;
        _startupHostedServiceHealthCheck = startupHostedServiceHealthCheck;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Startup Background Service is starting.");

        // Simulate the effect of a long-running startup task.
        Task.Run(async () =>
        {
            await Task.Delay(_delaySeconds * 1000);

            _startupHostedServiceHealthCheck.StartupTaskCompleted = true;

            _logger.LogInformation("Startup Background Service has started.");
        });

        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Startup Background Service is stopping.");

        return Task.CompletedTask;
    }

    public void Dispose()
    {
    }
}

Kontrola stavu je zaregistrovaná AddCheckStartup.ConfigureServices společně s hostovanými službami. Vzhledem k tomu, že hostovaná služba musí nastavit vlastnost kontroly stavu, je kontrola stavu také zaregistrovaná v kontejneru služby (LivenessProbeStartup.cs):

services.AddHostedService<StartupHostedService>();
services.AddSingleton<StartupHostedServiceHealthCheck>();

services.AddHealthChecks()
    .AddCheck<StartupHostedServiceHealthCheck>(
        "hosted_service_startup",
        failureStatus: HealthStatus.Degraded,
        tags: new[] { "ready" });

services.Configure<HealthCheckPublisherOptions>(options =>
{
    options.Delay = TimeSpan.FromSeconds(2);
    options.Predicate = (check) => check.Tags.Contains("ready");
});

services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();

Koncový bod kontroly stavu se vytvoří voláním MapHealthChecksStartup.Configure. V ukázkové aplikaci se koncové body kontroly stavu vytvoří na adrese:

  • /health/ready pro kontrolu připravenosti. Kontrola připravenosti filtruje kontroly stavu na kontrolu stavu pomocí značky ready .
  • /health/live pro kontrolu živého života. Kontrola aktivity filtruje StartupHostedServiceHealthCheck vrácením false se změnami (další informace najdete v HealthCheckOptions.Predicate tématu Kontroly stavu filtru).

V následujícím příkladu kódu:

  • Kontrola připravenosti používá všechny registrované kontroly se značkou Připraveno.
  • Vyloučí Predicate všechny kontroly a vrátí hodnotu 200-OK.
app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions()
    {
        Predicate = (check) => check.Tags.Contains("ready"),
    });

    endpoints.MapHealthChecks("/health/live", new HealthCheckOptions()
    {
        Predicate = (_) => false
    });
}

Pokud chcete spustit scénář konfigurace připravenosti a aktivity pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:

dotnet run --scenario liveness

V prohlížeči navštivte /health/ready několikrát, dokud nepřejde 15 sekund. Kontrola stavu hlásí Unhealthy prvních 15 sekund. Po 15 sekundách koncový bod hlásí Healthydokončení dlouhotrvající úlohy hostované služby.

Tento příklad také vytvoří vydavatele kontroly stavu (IHealthCheckPublisher implementaci), který spustí první kontrolu připravenosti se dvěma sekundami zpoždění. Další informace najdete v části Vydavatele kontroly stavu.

Příklad Kubernetes

Použití samostatných kontrol připravenosti a aktivity je užitečné v prostředí, jako je Kubernetes. V Kubernetes může být aplikace nutná ke spouštění časově náročných spouštěcích prací před přijetím požadavků, jako je například test dostupnosti podkladové databáze. Použití samostatných kontrol umožňuje orchestrátoru rozlišit, jestli aplikace funguje, ale ještě není připravená nebo jestli se aplikaci nepodařilo spustit. Další informace o testech připravenosti a aktivity v Kubernetes najdete v dokumentaci ke konfiguraci testů živé aktivity a připravenosti v Kubernetes.

Následující příklad ukazuje konfiguraci sondy připravenosti Kubernetes:

spec:
  template:
  spec:
    readinessProbe:
      # an http probe
      httpGet:
        path: /health/ready
        port: 80
      # length of time to wait for a pod to initialize
      # after pod startup, before applying health checking
      initialDelaySeconds: 30
      timeoutSeconds: 1
    ports:
      - containerPort: 80

Sonda založená na metrikách s vlastním zapisovačem odpovědí

Ukázková aplikace ukazuje kontrolu stavu paměti pomocí vlastního zapisovače odpovědí.

MemoryHealthCheck hlásí snížený stav, pokud aplikace používá více než danou prahovou hodnotu paměti (1 GB v ukázkové aplikaci). Obsahuje HealthCheckResult informace o uvolňování paměti (GC) pro aplikaci (MemoryHealthCheck.cs):

public class MemoryHealthCheck : IHealthCheck
{
    private readonly IOptionsMonitor<MemoryCheckOptions> _options;

    public MemoryHealthCheck(IOptionsMonitor<MemoryCheckOptions> options)
    {
        _options = options;
    }

    public string Name => "memory_check";

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        var options = _options.Get(context.Registration.Name);

        // Include GC information in the reported diagnostics.
        var allocated = GC.GetTotalMemory(forceFullCollection: false);
        var data = new Dictionary<string, object>()
        {
            { "AllocatedBytes", allocated },
            { "Gen0Collections", GC.CollectionCount(0) },
            { "Gen1Collections", GC.CollectionCount(1) },
            { "Gen2Collections", GC.CollectionCount(2) },
        };
        var status = (allocated < options.Threshold) ?
            HealthStatus.Healthy : context.Registration.FailureStatus;

        return Task.FromResult(new HealthCheckResult(
            status,
            description: "Reports degraded status if allocated bytes " +
                $">= {options.Threshold} bytes.",
            exception: null,
            data: data));
    }
}

Zaregistrujte služby kontroly stavu v adresáři AddHealthChecksStartup.ConfigureServices. Místo povolení kontroly stavu předáním AddCheckdo služby se zaregistruje MemoryHealthCheck jako služba. Všechny IHealthCheck registrované služby jsou k dispozici pro služby kontroly stavu a middleware. Doporučujeme registrovat služby kontroly stavu jako služby Singleton.

V CustomWriterStartup.cs ukázkové aplikaci:

services.AddHealthChecks()
    .AddMemoryHealthCheck("memory");

Koncový bod kontroly stavu se vytvoří voláním MapHealthChecksStartup.Configure. Delegát WriteResponse je k dispozici vlastnosti ResponseWriter , která při provádění kontroly stavu vypíše vlastní JSodpověď ON:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health", new HealthCheckOptions()
    {
        ResponseWriter = WriteResponse
    });
}

Delegát WriteResponse formátuje objekt CompositeHealthCheckResultJSON a vrátí JSvýstup ON pro odpověď kontroly stavu. Další informace najdete v části Přizpůsobení výstupu.

Pokud chcete spustit sondu založenou na metrikách s výstupem vlastního zapisovače odpovědí pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:

dotnet run --scenario writer

Poznámka:

AspNetCore.Diagnostics.HealthChecks zahrnuje scénáře kontroly stavu na základě metrik, včetně diskového úložiště a kontroly maximální hodnoty liveness.

AspNetCore.Diagnostics.HealthChecks není udržována ani podporována společností Microsoft.

Filtrovat podle portu

MapHealthChecks Volání RequireHost se vzorem adresy URL, který určuje port, který omezí požadavky kontroly stavu na zadaný port. Tento přístup se obvykle používá v prostředí kontejneru k vystavení portu pro monitorovací služby.

Ukázková aplikace nakonfiguruje port pomocí zprostředkovatele konfigurace proměnné prostředí. Port se nastaví v launchSettings.json souboru a předá zprostředkovateli konfigurace prostřednictvím proměnné prostředí. Musíte také nakonfigurovat server tak, aby naslouchal požadavkům na portu pro správu.

Pokud chcete ukázkovou aplikaci použít k předvedení konfigurace portů pro správu, vytvořte launchSettings.json soubor ve Properties složce.

Následující Properties/launchSettings.json soubor v ukázkové aplikaci není součástí souborů projektu ukázkové aplikace a musí být vytvořen ručně:

{
  "profiles": {
    "SampleApp": {
      "commandName": "Project",
      "commandLineArgs": "",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "ASPNETCORE_URLS": "http://localhost:5000/;http://localhost:5001/",
        "ASPNETCORE_MANAGEMENTPORT": "5001"
      },
      "applicationUrl": "http://localhost:5000/"
    }
  }
}

Zaregistrujte služby kontroly stavu v adresáři AddHealthChecksStartup.ConfigureServices. Vytvořte koncový bod kontroly stavu voláním MapHealthChecksStartup.Configure.

V ukázkové aplikaci volání RequireHost koncového bodu určuje Startup.Configure port pro správu z konfigurace:

endpoints.MapHealthChecks("/health")
    .RequireHost($"*:{Configuration["ManagementPort"]}");

Koncové body se vytvoří v ukázkové aplikaci v Startup.Configureaplikaci . V následujícím příkladu kódu:

  • Kontrola připravenosti používá všechny registrované kontroly se značkou Připraveno.
  • Vyloučí Predicate všechny kontroly a vrátí hodnotu 200-OK.
app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions()
    {
        Predicate = (check) => check.Tags.Contains("ready"),
    });

    endpoints.MapHealthChecks("/health/live", new HealthCheckOptions()
    {
        Predicate = (_) => false
    });
}

Poznámka:

V ukázkové aplikaci se můžete vyhnout vytváření launchSettings.json souboru nastavením portu pro správu explicitně v kódu. V Program.cs místě vytvoření HostBuilder přidejte volání ListenAnyIP a zadejte koncový bod portu pro správu aplikace. V Configure poli ManagementPortStartup.cs, zadejte port pro správu pomocí RequireHost:

Program.cs:

return new HostBuilder()
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseKestrel()
            .ConfigureKestrel(serverOptions =>
            {
                serverOptions.ListenAnyIP(5001);
            })
            .UseStartup(startupType);
    })
    .Build();

ManagementPortStartup.cs:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health").RequireHost("*:5001");
});

Pokud chcete spustit scénář konfigurace portu pro správu pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:

dotnet run --scenario port

Distribuce knihovny kontroly stavu

Distribuce kontroly stavu jako knihovny:

  1. Napište kontrolu stavu, která implementuje IHealthCheck rozhraní jako samostatnou třídu. Třída se může spoléhat na injektáž závislostí (DI), aktivaci typu a pojmenované možnosti pro přístup ke konfiguračním datům.

    V logice CheckHealthAsynckontrol stavu :

    • data1 a data2 používají se v metodě ke spuštění logiky kontroly stavu sondy.
    • AccessViolationException zpracovává se.

    Když dojde k chyběAccessViolationException, vrátí HealthCheckResult se funkce umožňující FailureStatus uživatelům konfigurovat stav selhání kontrol stavu.

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Extensions.Diagnostics.HealthChecks;
    
    namespace SampleApp
    {
        public class ExampleHealthCheck : IHealthCheck
        {
            private readonly string _data1;
            private readonly int? _data2;
    
            public ExampleHealthCheck(string data1, int? data2)
            {
                _data1 = data1 ?? throw new ArgumentNullException(nameof(data1));
                _data2 = data2 ?? throw new ArgumentNullException(nameof(data2));
            }
    
            public async Task<HealthCheckResult> CheckHealthAsync(
                HealthCheckContext context, CancellationToken cancellationToken)
            {
                try
                {
                    return HealthCheckResult.Healthy();
                }
                catch (AccessViolationException ex)
                {
                    return new HealthCheckResult(
                        context.Registration.FailureStatus,
                        description: "An access violation occurred during the check.",
                        exception: ex,
                        data: null);
                }
            }
        }
    }
    
  2. Napište metodu rozšíření s parametry, které spotřebová aplikace volá ve své Startup.Configure metodě. V následujícím příkladu předpokládejme následující podpis metody kontroly stavu:

    ExampleHealthCheck(string, string, int )
    

    Předchozí podpis označuje, že ExampleHealthCheck vyžaduje další data ke zpracování logiky sondy kontroly stavu. Data se poskytují delegátu použitému k vytvoření instance kontroly stavu při registraci kontroly stavu v metodě rozšíření. V následujícím příkladu volající určuje volitelné:

    • název kontroly stavu (name). Pokud nullse použije , example_health_check použije se.
    • datový bod řetězce pro kontrolu stavu (data1).
    • celočíselné datové body pro kontrolu stavu (data2). Pokud nullse použije , 1 použije se.
    • stav selhání (HealthStatus). Výchozí hodnota je null. HealthStatus.Unhealthy Pokud nullse zobrazí stav selhání, zobrazí se zpráva.
    • značky (IEnumerable<string>).
    using System.Collections.Generic;
    using Microsoft.Extensions.Diagnostics.HealthChecks;
    
    public static class ExampleHealthCheckBuilderExtensions
    {
        const string DefaultName = "example_health_check";
    
        public static IHealthChecksBuilder AddExampleHealthCheck(
            this IHealthChecksBuilder builder,
            string name = default,
            string data1,
            int data2 = 1,
            HealthStatus? failureStatus = default,
            IEnumerable<string> tags = default)
        {
            return builder.Add(new HealthCheckRegistration(
                name ?? DefaultName,
                sp => new ExampleHealthCheck(data1, data2),
                failureStatus,
                tags));
        }
    }
    

Kontrola stavu – Vydavatel

IHealthCheckPublisher Po přidání do kontejneru služby systém kontroly stavu pravidelně provádí kontroly stavu a volání PublishAsync s výsledkem. To je užitečné ve scénáři systému monitorování stavu založeného na nabízených oznámeních, který očekává, že každý proces bude pravidelně volat monitorovací systém, aby zjistil stav.

Rozhraní IHealthCheckPublisher má jednu metodu:

Task PublishAsync(HealthReport report, CancellationToken cancellationToken);

HealthCheckPublisherOptions povolit nastavení:

  • Delay: Počáteční prodleva použitá po spuštění aplikace před spuštěním IHealthCheckPublisher instancí. Zpoždění se použije jednou při spuštění a nevztahuje se na následné iterace. Výchozí hodnota je pět sekund.
  • Period: Období IHealthCheckPublisher provádění. Výchozí hodnota je 30 sekund.
  • Predicate: Pokud Predicate je null (výchozí), spustí služba vydavatele kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která filtruje sadu kontrol. Predikát se vyhodnocuje každé období.
  • Timeout: Časový limit pro provádění kontrol stavu pro všechny IHealthCheckPublisher instance. Slouží InfiniteTimeSpan ke spuštění bez časového limitu. Výchozí hodnota je 30 sekund.

V ukázkové aplikaci ReadinessPublisher je IHealthCheckPublisher implementace. Stav kontroly stavu se protokoluje pro každou kontrolu na úrovni protokolu:

public class ReadinessPublisher : IHealthCheckPublisher
{
    private readonly ILogger _logger;

    public ReadinessPublisher(ILogger<ReadinessPublisher> logger)
    {
        _logger = logger;
    }

    // The following example is for demonstration purposes only. Health Checks
    // Middleware already logs health checks results. A real-world readiness
    // check in a production app might perform a set of more expensive or
    // time-consuming checks to determine if other resources are responding
    // properly.
    public Task PublishAsync(HealthReport report,
        CancellationToken cancellationToken)
    {
        if (report.Status == HealthStatus.Healthy)
        {
            _logger.LogInformation("{Timestamp} Readiness Probe Status: {Result}",
                DateTime.UtcNow, report.Status);
        }
        else
        {
            _logger.LogError("{Timestamp} Readiness Probe Status: {Result}",
                DateTime.UtcNow, report.Status);
        }

        cancellationToken.ThrowIfCancellationRequested();

        return Task.CompletedTask;
    }
}

V příkladu LivenessProbeStartupStartupHostedService ukázkové aplikace má kontrola připravenosti dvě sekundy zpoždění spuštění a spustí kontrolu každých 30 sekund. K aktivaci IHealthCheckPublisher implementace se ukázka zaregistruje ReadinessPublisher jako jednoúčelová služba v kontejneru injektáže závislostí (DI ):

services.AddHostedService<StartupHostedService>();
services.AddSingleton<StartupHostedServiceHealthCheck>();

services.AddHealthChecks()
    .AddCheck<StartupHostedServiceHealthCheck>(
        "hosted_service_startup",
        failureStatus: HealthStatus.Degraded,
        tags: new[] { "ready" });

services.Configure<HealthCheckPublisherOptions>(options =>
{
    options.Delay = TimeSpan.FromSeconds(2);
    options.Predicate = (check) => check.Tags.Contains("ready");
});

services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();

Poznámka:

AspNetCore.Diagnostics.HealthCheckszahrnuje vydavatele pro několik systémů, včetně aplikačních Přehledy.

AspNetCore.Diagnostics.HealthChecks není udržována ani podporována společností Microsoft.

Omezení kontrol stavu pomocí MapWhen

Slouží MapWhen k podmíněnému větvení kanálu žádosti pro koncové body kontroly stavu.

V následujícím příkladu vytvoří větve kanálu požadavku, aby aktivoval Middleware kontroly stavu, MapWhen pokud se pro koncový bod obdrží api/HealthCheck požadavek GET:

app.MapWhen(
    context => context.Request.Method == HttpMethod.Get.Method && 
        context.Request.Path.StartsWith("/api/HealthCheck"),
    builder => builder.UseHealthChecks());

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
});

Další informace najdete v tématu Middleware ASP.NET Core.

ASP.NET Core nabízí middlewarové kontroly stavu a knihovny pro vytváření sestav stavu komponent infrastruktury aplikací.

Kontroly stavu jsou vystaveny aplikací jako koncové body HTTP. Koncové body kontroly stavu je možné nakonfigurovat pro různé scénáře monitorování v reálném čase:

  • Sondy stavu můžou používat orchestrátory kontejnerů a nástroje pro vyrovnávání zatížení ke kontrole stavu aplikace. Orchestrátor kontejnerů může například reagovat na neúspěšnou kontrolu stavu zastavením postupného nasazení nebo restartováním kontejneru. Nástroj pro vyrovnávání zatížení může reagovat na aplikaci, která není v pořádku, směrováním provozu mimo instanci, která selhává, do instance, která je v pořádku.
  • Použití paměti, disku a dalších prostředků fyzického serveru je možné monitorovat, aby byl stav v pořádku.
  • Kontroly stavu můžou otestovat závislosti aplikace, jako jsou databáze a koncové body externí služby, a ověřit dostupnost a normální fungování.

Zobrazení nebo stažení ukázkového kódu (postup stažení)

Ukázková aplikace obsahuje příklady scénářů popsaných v tomto článku. Pokud chcete spustit ukázkovou aplikaci pro daný scénář, použijte příkaz dotnet run ze složky projektu v příkazovém prostředí. Podrobnosti o používání ukázkové aplikace najdete v souboru ukázkové aplikace README.md a popisech scénářů v tomto článku.

Požadavky

Kontroly stavu se obvykle používají s externí službou monitorování nebo orchestrátorem kontejnerů ke kontrole stavu aplikace. Než do aplikace přidáte kontroly stavu, rozhodněte se, jaký monitorovací systém se má použít. Monitorovací systém určuje, jaké typy kontrol stavu se mají vytvořit a jak nakonfigurovat jejich koncové body.

Na Microsoft.AspNetCore.Diagnostics.HealthChecks balíček se implicitně odkazuje pro aplikace ASP.NET Core. Pokud chcete spouštět kontroly stavu pomocí Entity Framework Core, přidejte do balíčku odkaz na Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore balíček.

Ukázková aplikace poskytuje spouštěcí kód, který demonstruje kontroly stavu pro několik scénářů. Scénář sondy databáze kontroluje stav připojení k databázi pomocí AspNetCore.Diagnostics.HealthChecks. Scénář sondy DbContext kontroluje databázi pomocí .EF CoreDbContext Pokud chcete prozkoumat databázové scénáře, ukázková aplikace:

Poznámka:

AspNetCore.Diagnostics.HealthChecks není udržována ani podporována společností Microsoft.

Další scénář kontroly stavu ukazuje, jak filtrovat kontroly stavu na port pro správu. Ukázková aplikace vyžaduje, Properties/launchSettings.json abyste vytvořili soubor, který obsahuje adresu URL pro správu a port pro správu. Další informace najdete v části Filtrovat podle portu .

Základní sonda stavu

U mnoha aplikací stačí základní konfigurace sondy stavu, která hlásí dostupnost aplikace pro zpracování požadavků (živé aktivity) ke zjištění stavu aplikace.

Základní konfigurace registruje služby kontroly stavu a volá Middleware kontroly stavu, aby reagoval na koncový bod adresy URL s odpovědí na stav. Ve výchozím nastavení nejsou žádné konkrétní kontroly stavu registrovány k testování žádné konkrétní závislosti nebo subsystému. Aplikace se považuje za v pořádku, pokud může reagovat na adresu URL koncového bodu stavu. Výchozí zapisovač odpovědí zapíše stav (HealthStatus) jako odpověď ve formátu prostého textu zpět klientovi, který označuje HealthStatus.Healthyhodnotu , HealthStatus.Degradednebo HealthStatus.Unhealthy stav.

Zaregistrujte služby kontroly stavu v adresáři AddHealthChecksStartup.ConfigureServices. Vytvořte koncový bod kontroly stavu voláním MapHealthChecksStartup.Configure.

V ukázkové aplikaci se koncový bod kontroly stavu vytvoří na adrese /health (BasicStartup.cs):

public class BasicStartup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHealthChecks();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapHealthChecks("/health");
        });
    }
}

Pokud chcete spustit základní scénář konfigurace pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:

dotnet run --scenario basic

Příklad Dockeru

Docker nabízí integrovanou HEALTHCHECK direktivu, která se dá použít ke kontrole stavu aplikace, která používá základní konfiguraci kontroly stavu:

HEALTHCHECK CMD curl --fail http://localhost:5000/health || exit

Vytváření kontrol stavu

Kontroly stavu se vytvářejí implementací IHealthCheck rozhraní. Metoda CheckHealthAsync vrátí HealthCheckResult hodnotu, která označuje stav jako Healthy, Degradednebo Unhealthy. Výsledek se zapíše jako odpověď prostého textu s konfigurovatelným stavovým kódem (konfigurace je popsaná v části Možnosti kontroly stavu). HealthCheckResult může také vracet volitelné páry klíč-hodnota.

Následující ExampleHealthCheck třída ukazuje rozložení kontroly stavu. Logika kontroly stavu je umístěna CheckHealthAsync v metodě. Následující příklad nastaví fiktivní proměnnou , healthCheckResultHealthyna true. Pokud je hodnota healthCheckResultHealthy nastavena na false, HealthCheckResult.Unhealthy stav se vrátí.

public class ExampleHealthCheck : IHealthCheck
{
    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        var healthCheckResultHealthy = true;

        if (healthCheckResultHealthy)
        {
            return Task.FromResult(
                HealthCheckResult.Healthy("A healthy result."));
        }

        return Task.FromResult(
            HealthCheckResult.Unhealthy("An unhealthy result."));
    }
}

Registrace služeb kontroly stavu

Typ ExampleHealthCheck se přidá ke službám kontroly stavu s následujícími položkami AddCheckStartup.ConfigureServices:

services.AddHealthChecks()
    .AddCheck<ExampleHealthCheck>("example_health_check");

Přetížení AddCheck zobrazené v následujícím příkladu nastaví stav selhání (HealthStatus) tak, aby ohlásil, když kontrola stavu hlásí selhání. Pokud je stav selhání nastavený na null (výchozí), HealthStatus.Unhealthy je hlášeno. Toto přetížení je užitečný scénář pro autory knihoven, kde je stav selhání označený knihovnou vynucen aplikací, když dojde k selhání kontroly stavu, pokud implementace kontroly stavu dodržuje nastavení.

Značky lze použít k filtrování kontrol stavu (popsáno dále v části Kontroly stavu filtru).

services.AddHealthChecks()
    .AddCheck<ExampleHealthCheck>(
        "example_health_check",
        failureStatus: HealthStatus.Degraded,
        tags: new[] { "example" });

AddCheck může také spustit funkci lambda. V následujícím příkladu je název kontroly stavu zadán jako Example a kontrola vždy vrátí stav v pořádku:

services.AddHealthChecks()
    .AddCheck("Example", () =>
        HealthCheckResult.Healthy("Example is OK!"), tags: new[] { "example" });

Volání AddTypeActivatedCheck pro předání argumentů implementaci kontroly stavu V následujícím příkladu TestHealthCheckWithArgs přijímá celé číslo a řetězec pro použití, pokud CheckHealthAsync je volán:

private class TestHealthCheckWithArgs : IHealthCheck
{
    public TestHealthCheckWithArgs(int i, string s)
    {
        I = i;
        S = s;
    }

    public int I { get; set; }

    public string S { get; set; }

    public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, 
        CancellationToken cancellationToken = default)
    {
        ...
    }
}

TestHealthCheckWithArgs je registrován voláním AddTypeActivatedCheck celého čísla a řetězce předaného implementaci:

services.AddHealthChecks()
    .AddTypeActivatedCheck<TestHealthCheckWithArgs>(
        "test", 
        failureStatus: HealthStatus.Degraded, 
        tags: new[] { "example" }, 
        args: new object[] { 5, "string" });

Použití směrování kontrol stavu

MapHealthChecks Volání Startup.Configuretvůrce koncových bodů pomocí adresy URL koncového bodu nebo relativní cesty:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health");
});

Vyžadovat hostitele

Volání RequireHost pro zadání jednoho nebo více povolených hostitelů pro koncový bod kontroly stavu Hostitelé by měli mít místo punycode kódování Unicode a můžou obsahovat port. Pokud kolekci nezadáte, přijme se žádný hostitel.

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health").RequireHost("www.contoso.com:5001");
});

Další informace najdete v části Filtrovat podle portu .

Vyžadovat autorizaci

Volání RequireAuthorization pro spuštění autorizačního middlewaru na koncovém bodu žádosti o kontrolu stavu RequireAuthorization Přetížení přijímá jednu nebo více zásad autorizace. Pokud zásady nejsou zadané, použijí se výchozí zásady autorizace.

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health").RequireAuthorization();
});

Povolení žádostí nepůvodního zdroje (CORS)

I když spouštění kontrol stavu ručně z prohlížeče není běžným scénářem použití, middleware CORS je možné povolit voláním RequireCors koncových bodů kontrol stavu. RequireCors Přetížení přijímá delegátaCorsPolicyBuilder () nebo název zásady CORS. Pokud zásady nejsou zadané, použije se výchozí zásada CORS. Další informace najdete v tématu Povolení žádostí mezi zdroji (CORS) v ASP.NET Core.

Možnosti kontroly stavu

HealthCheckOptions poskytnout příležitost přizpůsobit chování kontroly stavu:

Filtrování kontrol stavu

Ve výchozím nastavení spustí Middleware kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která vrátí logickou hodnotu možnosti Predicate . V následujícím příkladu Bar se kontrola stavu vyfiltruje podle značky (bar_tag) v podmíněném příkazu funkce, kde true se vrátí pouze v případě, že se vlastnost kontroly Tags stavu shoduje foo_tag nebo baz_tag:

V Startup.ConfigureServices:

services.AddHealthChecks()
    .AddCheck("Foo", () =>
        HealthCheckResult.Healthy("Foo is OK!"), tags: new[] { "foo_tag" })
    .AddCheck("Bar", () =>
        HealthCheckResult.Unhealthy("Bar is unhealthy!"), tags: new[] { "bar_tag" })
    .AddCheck("Baz", () =>
        HealthCheckResult.Healthy("Baz is OK!"), tags: new[] { "baz_tag" });

Vyfiltruje Startup.ConfigurePredicate kontrolu stavu panelu. Pouze Foo a Baz provést:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health", new HealthCheckOptions()
    {
        Predicate = (check) => check.Tags.Contains("foo_tag") ||
            check.Tags.Contains("baz_tag")
    });
});

Přizpůsobení stavového kódu HTTP

Slouží ResultStatusCodes k přizpůsobení mapování stavu na stavové kódy HTTP. Následující StatusCodes přiřazení jsou výchozí hodnoty používané middlewarem. Změňte hodnoty stavového kódu tak, aby splňovaly vaše požadavky.

V Startup.Configure:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health", new HealthCheckOptions()
    {
        ResultStatusCodes =
        {
            [HealthStatus.Healthy] = StatusCodes.Status200OK,
            [HealthStatus.Degraded] = StatusCodes.Status200OK,
            [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
        }
    });
});

Potlačení hlaviček mezipaměti

AllowCachingResponses určuje, zda middleware kontroly stavu přidává hlavičky HTTP do odpovědi sondy, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je false hodnota (výchozí), middleware nastaví nebo přepíše Cache-ControlExpires, a Pragma hlavičky, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je truehodnota, middleware neupraví hlavičky mezipaměti odpovědi.

V Startup.Configure:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health", new HealthCheckOptions()
    {
        AllowCachingResponses = true
    });
});

Přizpůsobení výstupu

Nastavte Startup.Configuremožnost HealthCheckOptions.ResponseWriter delegáta pro zápis odpovědi:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health", new HealthCheckOptions()
    {
        ResponseWriter = WriteResponse
    });
});

Výchozí delegát zapíše minimální odpověď prostého textu s řetězcovou hodnotou HealthReport.Status. Následující vlastní delegáti vypíše vlastní JSodpověď ON.

První příklad z ukázkové aplikace ukazuje, jak používat System.Text.Json:

private static Task WriteResponse(HttpContext context, HealthReport result)
{
    context.Response.ContentType = "application/json; charset=utf-8";

    var options = new JsonWriterOptions
    {
        Indented = true
    };

    using (var stream = new MemoryStream())
    {
        using (var writer = new Utf8JsonWriter(stream, options))
        {
            writer.WriteStartObject();
            writer.WriteString("status", result.Status.ToString());
            writer.WriteStartObject("results");
            foreach (var entry in result.Entries)
            {
                writer.WriteStartObject(entry.Key);
                writer.WriteString("status", entry.Value.Status.ToString());
                writer.WriteString("description", entry.Value.Description);
                writer.WriteStartObject("data");
                foreach (var item in entry.Value.Data)
                {
                    writer.WritePropertyName(item.Key);
                    JsonSerializer.Serialize(
                        writer, item.Value, item.Value?.GetType() ??
                        typeof(object));
                }
                writer.WriteEndObject();
                writer.WriteEndObject();
            }
            writer.WriteEndObject();
            writer.WriteEndObject();
        }

        var json = Encoding.UTF8.GetString(stream.ToArray());

        return context.Response.WriteAsync(json);
    }
}

Druhý příklad ukazuje, jak používat Newtonsoft.Json:

private static Task WriteResponse(HttpContext context, HealthReport result)
{
    context.Response.ContentType = "application/json";

    var json = new JObject(
        new JProperty("status", result.Status.ToString()),
        new JProperty("results", new JObject(result.Entries.Select(pair =>
            new JProperty(pair.Key, new JObject(
                new JProperty("status", pair.Value.Status.ToString()),
                new JProperty("description", pair.Value.Description),
                new JProperty("data", new JObject(pair.Value.Data.Select(
                    p => new JProperty(p.Key, p.Value))))))))));

    return context.Response.WriteAsync(
        json.ToString(Formatting.Indented));
}

V ukázkové aplikaci zakomentujte direktivu preprocesoruSYSTEM_TEXT_JSON, aby bylo možné povolit Newtonsoft.Json verzi WriteResponse.CustomWriterStartup.cs

Rozhraní API pro kontroly stavu neposkytuje integrovanou podporu složitých JSformátů on return, protože formát je specifický pro váš výběr monitorovacího systému. Podle potřeby upravte odpověď v předchozích příkladech. Další informace o JSpři serializaci pomocí System.Text.Json, naleznete v tématu Jak serializovat a deserializovat JSON v .NET.

Sonda databáze

Kontrola stavu může zadat databázový dotaz, který se má spustit jako logický test, který indikuje, jestli databáze normálně reaguje.

Ukázková aplikace používá AspNetCore.Diagnostics.HealthChecksknihovnu kontroly stavu pro aplikace ASP.NET Core ke spuštění kontroly stavu v databázi SQL Serveru. AspNetCore.Diagnostics.HealthChecksSELECT 1 spustí dotaz na databázi, aby potvrdil, že připojení k databázi je v pořádku.

Upozorňující

Při kontrole připojení k databázi s dotazem zvolte dotaz, který se rychle vrátí. Přístup k dotazům riskuje přetížení databáze a snížení výkonu. Ve většině případů není spuštění testovacího dotazu nutné. Stačí pouze úspěšné připojení k databázi. Pokud zjistíte, že je nutné spustit dotaz, zvolte jednoduchý dotaz SELECT, například SELECT 1.

Zahrnout odkaz na AspNetCore.HealthChecks.SqlServerbalíček .

Do souboru ukázkové aplikace zadejte platný připojovací řetězec appsettings.json databáze. Aplikace používá databázi SQL Serveru s názvem HealthCheckSample:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=HealthCheckSample;Trusted_Connection=True;MultipleActiveResultSets=true;ConnectRetryCount=0"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    },
    "Console": {
      "IncludeScopes": "true"
    }
  },
  "AllowedHosts": "*"
}

Zaregistrujte služby kontroly stavu v adresáři AddHealthChecksStartup.ConfigureServices. Ukázková aplikace volá metodu AddSqlServer s připojovací řetězec databáze (DbHealthStartup.cs):

services.AddHealthChecks()
    .AddSqlServer(Configuration["ConnectionStrings:DefaultConnection"]);

Koncový bod kontroly stavu se vytvoří voláním MapHealthChecksStartup.Configure:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health");
}

Pokud chcete spustit scénář sondy databáze pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:

dotnet run --scenario db

Poznámka:

AspNetCore.Diagnostics.HealthChecks není udržována ani podporována společností Microsoft.

Sonda Entity Framework Core DbContext

Kontrola DbContext potvrzuje, že aplikace může komunikovat s databází nakonfigurovanou pro aplikaci EF CoreDbContext. Kontrola je podporovaná DbContext v aplikacích, které:

AddDbContextCheck<TContext>zaregistruje kontrolu stavu pro DbContext Tato DbContext metoda je zadána TContext jako metoda. K dispozici je přetížení ke konfiguraci stavu selhání, značek a vlastního testovacího dotazu.

Standardně:

  • EF CoreCanConnectAsync Volání DbContextHealthCheck metody. Můžete přizpůsobit, jakou operaci se spustí při kontrole stavu pomocí AddDbContextCheck přetížení metod.
  • Název kontroly stavu je název TContext typu.

V ukázkové aplikaci AppDbContext se poskytuje AddDbContextCheck a zaregistruje jako služba v Startup.ConfigureServices :DbContextHealthStartup.cs

services.AddHealthChecks()
    .AddDbContextCheck<AppDbContext>();

services.AddDbContext<AppDbContext>(options =>
{
    options.UseSqlServer(
        Configuration["ConnectionStrings:DefaultConnection"]);
});

Koncový bod kontroly stavu se vytvoří voláním MapHealthChecksStartup.Configure:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health");
}

Pokud chcete spustit scénář sondy DbContext pomocí ukázkové aplikace, ověřte, že databáze zadaná připojovací řetězec v instanci SQL Serveru neexistuje. Pokud databáze existuje, odstraňte ji.

V příkazovém prostředí spusťte následující příkaz ze složky projektu:

dotnet run --scenario dbcontext

Po spuštění aplikace zkontrolujte stav provedením požadavku na /health koncový bod v prohlížeči. Databáze a AppDbContext neexistuje, takže aplikace poskytuje následující odpověď:

Unhealthy

Aktivujte ukázkovou aplikaci a vytvořte databázi. Vytvořte žádost na /createdatabase. Aplikace reaguje:

Creating the database...
Done!
Navigate to /health to see the health status.

Vytvořte požadavek na /health koncový bod. Databáze a kontext existují, takže aplikace reaguje:

Healthy

Aktivujte ukázkovou aplikaci, aby se databáze odstranila. Vytvořte žádost na /deletedatabase. Aplikace reaguje:

Deleting the database...
Done!
Navigate to /health to see the health status.

Vytvořte požadavek na /health koncový bod. Aplikace poskytuje odpověď, která není v pořádku:

Unhealthy

Samostatné testy připravenosti a aktivity

V některých scénářích hostování se k rozlišení dvou stavů aplikace používá pár kontrol stavu:

  • Připravenost označuje, jestli aplikace běží normálně, ale není připravená přijímat žádosti.
  • Liveness označuje, jestli se aplikace chybově ukončila a musí se restartovat.

Představte si následující příklad: Aplikace musí stáhnout velký konfigurační soubor, než bude připraven zpracovávat požadavky. Nechceme, aby se aplikace restartovala, pokud se počáteční stahování nezdaří, protože aplikace může několikrát zkusit stáhnout soubor znovu. K popisu aktivity procesu používáme sondu živé aktivity, nespustíme žádné další kontroly. Chceme také zabránit tomu, aby se žádosti odesílaly do aplikace před úspěšným stažením konfiguračního souboru. Sondu připravenosti použijeme k označení stavu "nepřipraveno", dokud stahování nebude úspěšné a aplikace bude připravená přijímat žádosti.

Ukázková aplikace obsahuje kontrolu stavu, která hlásí dokončení dlouhotrvající spouštěcí úlohy v hostované službě. Zpřístupňuje StartupHostedServiceHealthCheck vlastnost, StartupTaskCompletedkterou hostovaná služba může nastavit na true po dokončení dlouhotrvající úlohy (StartupHostedServiceHealthCheck.cs):

public class StartupHostedServiceHealthCheck : IHealthCheck
{
    private volatile bool _startupTaskCompleted = false;

    public string Name => "slow_dependency_check";

    public bool StartupTaskCompleted
    {
        get => _startupTaskCompleted;
        set => _startupTaskCompleted = value;
    }

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        if (StartupTaskCompleted)
        {
            return Task.FromResult(
                HealthCheckResult.Healthy("The startup task is finished."));
        }

        return Task.FromResult(
            HealthCheckResult.Unhealthy("The startup task is still running."));
    }
}

Dlouhotrvající úloha na pozadí je spuštěna hostované službou (Services/StartupHostedService). Na závěr úkolu StartupHostedServiceHealthCheck.StartupTaskCompleted je nastaveno:true

public class StartupHostedService : IHostedService, IDisposable
{
    private readonly int _delaySeconds = 15;
    private readonly ILogger _logger;
    private readonly StartupHostedServiceHealthCheck _startupHostedServiceHealthCheck;

    public StartupHostedService(ILogger<StartupHostedService> logger,
        StartupHostedServiceHealthCheck startupHostedServiceHealthCheck)
    {
        _logger = logger;
        _startupHostedServiceHealthCheck = startupHostedServiceHealthCheck;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Startup Background Service is starting.");

        // Simulate the effect of a long-running startup task.
        Task.Run(async () =>
        {
            await Task.Delay(_delaySeconds * 1000);

            _startupHostedServiceHealthCheck.StartupTaskCompleted = true;

            _logger.LogInformation("Startup Background Service has started.");
        });

        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Startup Background Service is stopping.");

        return Task.CompletedTask;
    }

    public void Dispose()
    {
    }
}

Kontrola stavu je zaregistrovaná AddCheckStartup.ConfigureServices společně s hostovanými službami. Vzhledem k tomu, že hostovaná služba musí nastavit vlastnost kontroly stavu, je kontrola stavu také zaregistrovaná v kontejneru služby (LivenessProbeStartup.cs):

services.AddHostedService<StartupHostedService>();
services.AddSingleton<StartupHostedServiceHealthCheck>();

services.AddHealthChecks()
    .AddCheck<StartupHostedServiceHealthCheck>(
        "hosted_service_startup",
        failureStatus: HealthStatus.Degraded,
        tags: new[] { "ready" });

services.Configure<HealthCheckPublisherOptions>(options =>
{
    options.Delay = TimeSpan.FromSeconds(2);
    options.Predicate = (check) => check.Tags.Contains("ready");
});

services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();

Koncový bod kontroly stavu se vytvoří voláním MapHealthChecksStartup.Configure. V ukázkové aplikaci se koncové body kontroly stavu vytvoří na adrese:

  • /health/ready pro kontrolu připravenosti. Kontrola připravenosti filtruje kontroly stavu na kontrolu stavu pomocí značky ready .
  • /health/live pro kontrolu živého života. Kontrola aktivity filtruje StartupHostedServiceHealthCheck vrácením false se změnami (další informace najdete v HealthCheckOptions.Predicate tématu Kontroly stavu filtru).

V následujícím příkladu kódu:

  • Kontrola připravenosti používá všechny registrované kontroly se značkou Připraveno.
  • Vyloučí Predicate všechny kontroly a vrátí hodnotu 200-OK.
app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions()
    {
        Predicate = (check) => check.Tags.Contains("ready"),
    });

    endpoints.MapHealthChecks("/health/live", new HealthCheckOptions()
    {
        Predicate = (_) => false
    });
}

Pokud chcete spustit scénář konfigurace připravenosti a aktivity pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:

dotnet run --scenario liveness

V prohlížeči navštivte /health/ready několikrát, dokud nepřejde 15 sekund. Kontrola stavu hlásí Unhealthy prvních 15 sekund. Po 15 sekundách koncový bod hlásí Healthydokončení dlouhotrvající úlohy hostované služby.

Tento příklad také vytvoří vydavatele kontroly stavu (IHealthCheckPublisher implementaci), který spustí první kontrolu připravenosti se dvěma sekundami zpoždění. Další informace najdete v části Vydavatele kontroly stavu.

Příklad Kubernetes

Použití samostatných kontrol připravenosti a aktivity je užitečné v prostředí, jako je Kubernetes. V Kubernetes může být aplikace nutná ke spouštění časově náročných spouštěcích prací před přijetím požadavků, jako je například test dostupnosti podkladové databáze. Použití samostatných kontrol umožňuje orchestrátoru rozlišit, jestli aplikace funguje, ale ještě není připravená nebo jestli se aplikaci nepodařilo spustit. Další informace o testech připravenosti a aktivity v Kubernetes najdete v dokumentaci ke konfiguraci testů živé aktivity a připravenosti v Kubernetes.

Následující příklad ukazuje konfiguraci sondy připravenosti Kubernetes:

spec:
  template:
  spec:
    readinessProbe:
      # an http probe
      httpGet:
        path: /health/ready
        port: 80
      # length of time to wait for a pod to initialize
      # after pod startup, before applying health checking
      initialDelaySeconds: 30
      timeoutSeconds: 1
    ports:
      - containerPort: 80

Sonda založená na metrikách s vlastním zapisovačem odpovědí

Ukázková aplikace ukazuje kontrolu stavu paměti pomocí vlastního zapisovače odpovědí.

MemoryHealthCheck hlásí snížený stav, pokud aplikace používá více než danou prahovou hodnotu paměti (1 GB v ukázkové aplikaci). Obsahuje HealthCheckResult informace o uvolňování paměti (GC) pro aplikaci (MemoryHealthCheck.cs):

public class MemoryHealthCheck : IHealthCheck
{
    private readonly IOptionsMonitor<MemoryCheckOptions> _options;

    public MemoryHealthCheck(IOptionsMonitor<MemoryCheckOptions> options)
    {
        _options = options;
    }

    public string Name => "memory_check";

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        var options = _options.Get(context.Registration.Name);

        // Include GC information in the reported diagnostics.
        var allocated = GC.GetTotalMemory(forceFullCollection: false);
        var data = new Dictionary<string, object>()
        {
            { "AllocatedBytes", allocated },
            { "Gen0Collections", GC.CollectionCount(0) },
            { "Gen1Collections", GC.CollectionCount(1) },
            { "Gen2Collections", GC.CollectionCount(2) },
        };
        var status = (allocated < options.Threshold) ?
            HealthStatus.Healthy : context.Registration.FailureStatus;

        return Task.FromResult(new HealthCheckResult(
            status,
            description: "Reports degraded status if allocated bytes " +
                $">= {options.Threshold} bytes.",
            exception: null,
            data: data));
    }
}

Zaregistrujte služby kontroly stavu v adresáři AddHealthChecksStartup.ConfigureServices. Místo povolení kontroly stavu předáním AddCheckdo služby se zaregistruje MemoryHealthCheck jako služba. Všechny IHealthCheck registrované služby jsou k dispozici pro služby kontroly stavu a middleware. Doporučujeme registrovat služby kontroly stavu jako služby Singleton.

V CustomWriterStartup.cs ukázkové aplikaci:

services.AddHealthChecks()
    .AddMemoryHealthCheck("memory");

Koncový bod kontroly stavu se vytvoří voláním MapHealthChecksStartup.Configure. Delegát WriteResponse je k dispozici vlastnosti ResponseWriter , která při provádění kontroly stavu vypíše vlastní JSodpověď ON:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health", new HealthCheckOptions()
    {
        ResponseWriter = WriteResponse
    });
}

Delegát WriteResponse formátuje objekt CompositeHealthCheckResultJSON a vrátí JSvýstup ON pro odpověď kontroly stavu. Další informace najdete v části Přizpůsobení výstupu.

Pokud chcete spustit sondu založenou na metrikách s výstupem vlastního zapisovače odpovědí pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:

dotnet run --scenario writer

Poznámka:

AspNetCore.Diagnostics.HealthChecks zahrnuje scénáře kontroly stavu na základě metrik, včetně diskového úložiště a kontroly maximální hodnoty liveness.

AspNetCore.Diagnostics.HealthChecks není udržována ani podporována společností Microsoft.

Filtrovat podle portu

MapHealthChecks Volání RequireHost se vzorem adresy URL, který určuje port, který omezí požadavky kontroly stavu na zadaný port. Tento přístup se obvykle používá v prostředí kontejneru k vystavení portu pro monitorovací služby.

Ukázková aplikace nakonfiguruje port pomocí zprostředkovatele konfigurace proměnné prostředí. Port se nastaví v launchSettings.json souboru a předá zprostředkovateli konfigurace prostřednictvím proměnné prostředí. Musíte také nakonfigurovat server tak, aby naslouchal požadavkům na portu pro správu.

Pokud chcete ukázkovou aplikaci použít k předvedení konfigurace portů pro správu, vytvořte launchSettings.json soubor ve Properties složce.

Následující Properties/launchSettings.json soubor v ukázkové aplikaci není součástí souborů projektu ukázkové aplikace a musí být vytvořen ručně:

{
  "profiles": {
    "SampleApp": {
      "commandName": "Project",
      "commandLineArgs": "",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "ASPNETCORE_URLS": "http://localhost:5000/;http://localhost:5001/",
        "ASPNETCORE_MANAGEMENTPORT": "5001"
      },
      "applicationUrl": "http://localhost:5000/"
    }
  }
}

Zaregistrujte služby kontroly stavu v adresáři AddHealthChecksStartup.ConfigureServices. Vytvořte koncový bod kontroly stavu voláním MapHealthChecksStartup.Configure.

V ukázkové aplikaci volání RequireHost koncového bodu určuje Startup.Configure port pro správu z konfigurace:

endpoints.MapHealthChecks("/health")
    .RequireHost($"*:{Configuration["ManagementPort"]}");

Koncové body se vytvoří v ukázkové aplikaci v Startup.Configureaplikaci . V následujícím příkladu kódu:

  • Kontrola připravenosti používá všechny registrované kontroly se značkou Připraveno.
  • Vyloučí Predicate všechny kontroly a vrátí hodnotu 200-OK.
app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions()
    {
        Predicate = (check) => check.Tags.Contains("ready"),
    });

    endpoints.MapHealthChecks("/health/live", new HealthCheckOptions()
    {
        Predicate = (_) => false
    });
}

Poznámka:

V ukázkové aplikaci se můžete vyhnout vytváření launchSettings.json souboru nastavením portu pro správu explicitně v kódu. V Program.cs místě vytvoření HostBuilder přidejte volání ListenAnyIP a zadejte koncový bod portu pro správu aplikace. V Configure poli ManagementPortStartup.cs, zadejte port pro správu pomocí RequireHost:

Program.cs:

return new HostBuilder()
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseKestrel()
            .ConfigureKestrel(serverOptions =>
            {
                serverOptions.ListenAnyIP(5001);
            })
            .UseStartup(startupType);
    })
    .Build();

ManagementPortStartup.cs:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health").RequireHost("*:5001");
});

Pokud chcete spustit scénář konfigurace portu pro správu pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:

dotnet run --scenario port

Distribuce knihovny kontroly stavu

Distribuce kontroly stavu jako knihovny:

  1. Napište kontrolu stavu, která implementuje IHealthCheck rozhraní jako samostatnou třídu. Třída se může spoléhat na injektáž závislostí (DI), aktivaci typu a pojmenované možnosti pro přístup ke konfiguračním datům.

    V logice CheckHealthAsynckontrol stavu :

    • data1 a data2 používají se v metodě ke spuštění logiky kontroly stavu sondy.
    • AccessViolationException zpracovává se.

    Když dojde k chyběAccessViolationException, vrátí HealthCheckResult se funkce umožňující FailureStatus uživatelům konfigurovat stav selhání kontrol stavu.

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Extensions.Diagnostics.HealthChecks;
    
    namespace SampleApp
    {
        public class ExampleHealthCheck : IHealthCheck
        {
            private readonly string _data1;
            private readonly int? _data2;
    
            public ExampleHealthCheck(string data1, int? data2)
            {
                _data1 = data1 ?? throw new ArgumentNullException(nameof(data1));
                _data2 = data2 ?? throw new ArgumentNullException(nameof(data2));
            }
    
            public async Task<HealthCheckResult> CheckHealthAsync(
                HealthCheckContext context, CancellationToken cancellationToken)
            {
                try
                {
                    return HealthCheckResult.Healthy();
                }
                catch (AccessViolationException ex)
                {
                    return new HealthCheckResult(
                        context.Registration.FailureStatus,
                        description: "An access violation occurred during the check.",
                        exception: ex,
                        data: null);
                }
            }
        }
    }
    
  2. Napište metodu rozšíření s parametry, které spotřebová aplikace volá ve své Startup.Configure metodě. V následujícím příkladu předpokládejme následující podpis metody kontroly stavu:

    ExampleHealthCheck(string, string, int )
    

    Předchozí podpis označuje, že ExampleHealthCheck vyžaduje další data ke zpracování logiky sondy kontroly stavu. Data se poskytují delegátu použitému k vytvoření instance kontroly stavu při registraci kontroly stavu v metodě rozšíření. V následujícím příkladu volající určuje volitelné:

    • název kontroly stavu (name). Pokud nullse použije , example_health_check použije se.
    • datový bod řetězce pro kontrolu stavu (data1).
    • celočíselné datové body pro kontrolu stavu (data2). Pokud nullse použije , 1 použije se.
    • stav selhání (HealthStatus). Výchozí hodnota je null. HealthStatus.Unhealthy Pokud nullse zobrazí stav selhání, zobrazí se zpráva.
    • značky (IEnumerable<string>).
    using System.Collections.Generic;
    using Microsoft.Extensions.Diagnostics.HealthChecks;
    
    public static class ExampleHealthCheckBuilderExtensions
    {
        const string DefaultName = "example_health_check";
    
        public static IHealthChecksBuilder AddExampleHealthCheck(
            this IHealthChecksBuilder builder,
            string name = default,
            string data1,
            int data2 = 1,
            HealthStatus? failureStatus = default,
            IEnumerable<string> tags = default)
        {
            return builder.Add(new HealthCheckRegistration(
                name ?? DefaultName,
                sp => new ExampleHealthCheck(data1, data2),
                failureStatus,
                tags));
        }
    }
    

Kontrola stavu – Vydavatel

IHealthCheckPublisher Po přidání do kontejneru služby systém kontroly stavu pravidelně provádí kontroly stavu a volání PublishAsync s výsledkem. To je užitečné ve scénáři systému monitorování stavu založeného na nabízených oznámeních, který očekává, že každý proces bude pravidelně volat monitorovací systém, aby zjistil stav.

Rozhraní IHealthCheckPublisher má jednu metodu:

Task PublishAsync(HealthReport report, CancellationToken cancellationToken);

HealthCheckPublisherOptions povolit nastavení:

  • Delay: Počáteční prodleva použitá po spuštění aplikace před spuštěním IHealthCheckPublisher instancí. Zpoždění se použije jednou při spuštění a nevztahuje se na následné iterace. Výchozí hodnota je pět sekund.
  • Period: Období IHealthCheckPublisher provádění. Výchozí hodnota je 30 sekund.
  • Predicate: Pokud Predicate je null (výchozí), spustí služba vydavatele kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která filtruje sadu kontrol. Predikát se vyhodnocuje každé období.
  • Timeout: Časový limit pro provádění kontrol stavu pro všechny IHealthCheckPublisher instance. Slouží InfiniteTimeSpan ke spuštění bez časového limitu. Výchozí hodnota je 30 sekund.

V ukázkové aplikaci ReadinessPublisher je IHealthCheckPublisher implementace. Stav kontroly stavu se protokoluje pro každou kontrolu na úrovni protokolu:

public class ReadinessPublisher : IHealthCheckPublisher
{
    private readonly ILogger _logger;

    public ReadinessPublisher(ILogger<ReadinessPublisher> logger)
    {
        _logger = logger;
    }

    // The following example is for demonstration purposes only. Health Checks
    // Middleware already logs health checks results. A real-world readiness
    // check in a production app might perform a set of more expensive or
    // time-consuming checks to determine if other resources are responding
    // properly.
    public Task PublishAsync(HealthReport report,
        CancellationToken cancellationToken)
    {
        if (report.Status == HealthStatus.Healthy)
        {
            _logger.LogInformation("{Timestamp} Readiness Probe Status: {Result}",
                DateTime.UtcNow, report.Status);
        }
        else
        {
            _logger.LogError("{Timestamp} Readiness Probe Status: {Result}",
                DateTime.UtcNow, report.Status);
        }

        cancellationToken.ThrowIfCancellationRequested();

        return Task.CompletedTask;
    }
}

V příkladu LivenessProbeStartupStartupHostedService ukázkové aplikace má kontrola připravenosti dvě sekundy zpoždění spuštění a spustí kontrolu každých 30 sekund. K aktivaci IHealthCheckPublisher implementace se ukázka zaregistruje ReadinessPublisher jako jednoúčelová služba v kontejneru injektáže závislostí (DI ):

services.AddHostedService<StartupHostedService>();
services.AddSingleton<StartupHostedServiceHealthCheck>();

services.AddHealthChecks()
    .AddCheck<StartupHostedServiceHealthCheck>(
        "hosted_service_startup",
        failureStatus: HealthStatus.Degraded,
        tags: new[] { "ready" });

services.Configure<HealthCheckPublisherOptions>(options =>
{
    options.Delay = TimeSpan.FromSeconds(2);
    options.Predicate = (check) => check.Tags.Contains("ready");
});

services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();

Poznámka:

AspNetCore.Diagnostics.HealthCheckszahrnuje vydavatele pro několik systémů, včetně aplikačních Přehledy.

AspNetCore.Diagnostics.HealthChecks není udržována ani podporována společností Microsoft.

Omezení kontrol stavu pomocí MapWhen

Slouží MapWhen k podmíněnému větvení kanálu žádosti pro koncové body kontroly stavu.

V následujícím příkladu vytvoří větve kanálu požadavku, aby aktivoval Middleware kontroly stavu, MapWhen pokud se pro koncový bod obdrží api/HealthCheck požadavek GET:

app.MapWhen(
    context => context.Request.Method == HttpMethod.Get.Method && 
        context.Request.Path.StartsWith("/api/HealthCheck"),
    builder => builder.UseHealthChecks());

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
});

Další informace najdete v tématu Middleware ASP.NET Core.

ASP.NET Core nabízí middlewarové kontroly stavu a knihovny pro vytváření sestav stavu komponent infrastruktury aplikací.

Kontroly stavu jsou vystaveny aplikací jako koncové body HTTP. Koncové body kontroly stavu je možné nakonfigurovat pro různé scénáře monitorování v reálném čase:

  • Sondy stavu můžou používat orchestrátory kontejnerů a nástroje pro vyrovnávání zatížení ke kontrole stavu aplikace. Orchestrátor kontejnerů může například reagovat na neúspěšnou kontrolu stavu zastavením postupného nasazení nebo restartováním kontejneru. Nástroj pro vyrovnávání zatížení může reagovat na aplikaci, která není v pořádku, směrováním provozu mimo instanci, která selhává, do instance, která je v pořádku.
  • Použití paměti, disku a dalších prostředků fyzického serveru je možné monitorovat, aby byl stav v pořádku.
  • Kontroly stavu můžou otestovat závislosti aplikace, jako jsou databáze a koncové body externí služby, a ověřit dostupnost a normální fungování.

Kontroly stavu se obvykle používají s externí službou monitorování nebo orchestrátorem kontejnerů ke kontrole stavu aplikace. Než do aplikace přidáte kontroly stavu, rozhodněte se, jaký monitorovací systém se má použít. Monitorovací systém určuje, jaké typy kontrol stavu se mají vytvořit a jak nakonfigurovat jejich koncové body.

Základní sonda stavu

U mnoha aplikací stačí základní konfigurace sondy stavu, která hlásí dostupnost aplikace pro zpracování požadavků (živé aktivity) ke zjištění stavu aplikace.

Základní konfigurace registruje služby kontroly stavu a volá Middleware kontroly stavu, aby reagoval na koncový bod adresy URL s odpovědí na stav. Ve výchozím nastavení nejsou žádné konkrétní kontroly stavu registrovány k testování žádné konkrétní závislosti nebo subsystému. Aplikace se považuje za v pořádku, pokud může reagovat na adresu URL koncového bodu stavu. Výchozí zapisovač odpovědí zapíše HealthStatus jako odpověď prostého textu klientovi. Je HealthStatusHealthStatus.Healthyto , HealthStatus.Degradednebo HealthStatus.Unhealthy.

Zaregistrujte služby kontroly stavu v adresáři AddHealthChecksProgram.cs. Vytvořte koncový bod kontroly stavu voláním MapHealthChecks.

Následující příklad vytvoří koncový bod kontroly stavu na /healthzadrese:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHealthChecks();

var app = builder.Build();

app.MapHealthChecks("/healthz");

app.Run();

DockeruHEALTHCHECK

Docker nabízí integrovanou HEALTHCHECK direktivu, která se dá použít ke kontrole stavu aplikace, která používá základní konfiguraci kontroly stavu:

HEALTHCHECK CMD curl --fail http://localhost:5000/healthz || exit

Předchozí příklad používá curl k vytvoření požadavku HTTP na koncový bod kontroly stavu na /healthzadrese . curl není součástí imagí kontejneru .NET Linux, ale dá se přidat instalací požadovaného balíčku do souboru Dockerfile. Kontejnery, které používají image založené na Alpine Linuxu, můžou místo zahrnutí wgetcurlpoužít .

Vytváření kontrol stavu

Kontroly stavu se vytvářejí implementací IHealthCheck rozhraní. Metoda CheckHealthAsync vrátí HealthCheckResult hodnotu, která označuje stav jako Healthy, Degradednebo Unhealthy. Výsledek se zapíše jako odpověď ve formátu prostého textu s konfigurovatelným stavovým kódem. Konfigurace je popsaná v části Možnosti kontroly stavu. HealthCheckResult může také vracet volitelné páry klíč-hodnota.

Následující příklad ukazuje rozložení kontroly stavu:

public class SampleHealthCheck : IHealthCheck
{
    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        var isHealthy = true;

        // ...

        if (isHealthy)
        {
            return Task.FromResult(
                HealthCheckResult.Healthy("A healthy result."));
        }

        return Task.FromResult(
            new HealthCheckResult(
                context.Registration.FailureStatus, "An unhealthy result."));
    }
}

Logika kontroly stavu je umístěna v CheckHealthAsync metodě. Předchozí příklad nastaví fiktivní proměnnou , isHealthyna true. Pokud je hodnota isHealthy nastavena na false, HealthCheckRegistration.FailureStatus stav se vrátí.

Pokud CheckHealthAsync při kontrole vyvolá výjimku, vrátí se nová HealthReportEntry hodnota s nastavenou HealthReportEntry.Status na FailureStatushodnotu . Tento stav je definován ( AddCheck viz část Služby kontroly stavu) a obsahuje vnitřní výjimku , která způsobila selhání kontroly. Je Description nastavená na zprávu výjimky.

Registrace služeb kontroly stavu

Pokud chcete zaregistrovat službu kontroly stavu, zavolejte AddCheck do Program.cs:

builder.Services.AddHealthChecks()
    .AddCheck<SampleHealthCheck>("Sample");

Přetížení AddCheck zobrazené v následujícím příkladu nastaví stav selhání (HealthStatus) tak, aby ohlásil, když kontrola stavu hlásí selhání. Pokud je stav selhání nastavený na null (výchozí), HealthStatus.Unhealthy je hlášeno. Toto přetížení je užitečný scénář pro autory knihoven, kde je stav selhání označený knihovnou vynucen aplikací, když dojde k selhání kontroly stavu, pokud implementace kontroly stavu dodržuje nastavení.

Značky lze použít k filtrování kontrol stavu. Značky jsou popsány v části Kontroly stavu filtru.

builder.Services.AddHealthChecks()
    .AddCheck<SampleHealthCheck>(
        "Sample",
        failureStatus: HealthStatus.Degraded,
        tags: new[] { "sample" });

AddCheck může také spustit funkci lambda. V následujícím příkladu vrátí kontrola stavu vždy výsledek, který je v pořádku:

builder.Services.AddHealthChecks()
    .AddCheck("Sample", () => HealthCheckResult.Healthy("A healthy result."));

Volání AddTypeActivatedCheck pro předání argumentů implementaci kontroly stavu V následujícím příkladu přijímá kontrola stavu aktivovaná typem celé číslo a řetězec v jeho konstruktoru:

public class SampleHealthCheckWithArgs : IHealthCheck
{
    private readonly int _arg1;
    private readonly string _arg2;

    public SampleHealthCheckWithArgs(int arg1, string arg2)
        => (_arg1, _arg2) = (arg1, arg2);

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        // ...

        return Task.FromResult(HealthCheckResult.Healthy("A healthy result."));
    }
}

Pokud chcete zaregistrovat předchozí kontrolu stavu, zavolejte AddTypeActivatedCheck celé číslo a řetězec předaný jako argumenty:

builder.Services.AddHealthChecks()
    .AddTypeActivatedCheck<SampleHealthCheckWithArgs>(
        "Sample",
        failureStatus: HealthStatus.Degraded,
        tags: new[] { "sample" },
        args: new object[] { 1, "Arg" });

Použití směrování kontrol stavu

MapHealthChecks Volání Program.cstvůrce koncových bodů pomocí adresy URL koncového bodu nebo relativní cesty:

app.MapHealthChecks("/healthz");

Vyžadovat hostitele

Volání RequireHost pro zadání jednoho nebo více povolených hostitelů pro koncový bod kontroly stavu Hostitelé by měli mít místo punycode kódování Unicode a můžou obsahovat port. Pokud kolekci nezadáte, přijme se žádný hostitel:

app.MapHealthChecks("/healthz")
    .RequireHost("www.contoso.com:5001");

Chcete-li omezit koncový bod kontroly stavu tak, aby reagoval pouze na konkrétním portu, zadejte port v volání RequireHost. Tento přístup se obvykle používá v prostředí kontejneru k zveřejnění portu pro monitorovací služby:

app.MapHealthChecks("/healthz")
    .RequireHost("*:5001");

Upozorňující

Rozhraní API, které závisí na hlavičce hostitele, například HttpRequest.Host a RequireHost, podléhají potenciálnímu falšování identity klienty.

Pokud chcete zabránit falšování identity hostitele a portu, použijte jeden z následujících přístupů:

Pokud chcete zabránit neoprávněným klientům v falšování identity portu, zavolejte RequireAuthorization:

app.MapHealthChecks("/healthz")
    .RequireHost("*:5001")
    .RequireAuthorization();

Další informace naleznete v tématu Porovnávání hostitelů v trasách s RequireHost.

Vyžadovat autorizaci

Volání RequireAuthorization pro spuštění autorizačního middlewaru na koncovém bodu žádosti o kontrolu stavu RequireAuthorization Přetížení přijímá jednu nebo více zásad autorizace. Pokud zásady nejsou zadané, použije se výchozí zásada autorizace:

app.MapHealthChecks("/healthz")
    .RequireAuthorization();

Povolení žádostí nepůvodního zdroje (CORS)

I když spouštění kontrol stavu ručně z prohlížeče není běžným scénářem, middleware CORS je možné povolit voláním RequireCors koncových bodů kontrol stavu. Přetížení RequireCors přijímá delegáta tvůrce zásad CORS (CorsPolicyBuilder) nebo název zásady. Další informace najdete v tématu Povolení žádostí mezi zdroji (CORS) v ASP.NET Core.

Možnosti kontroly stavu

HealthCheckOptions poskytnout příležitost přizpůsobit chování kontroly stavu:

Filtrování kontrol stavu

Ve výchozím nastavení spustí Middleware kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která vrátí logickou hodnotu možnosti Predicate .

Následující příklad filtruje kontroly stavu tak, aby se spustily pouze ty, které jsou označené jako spuštěné sample :

app.MapHealthChecks("/healthz", new HealthCheckOptions
{
    Predicate = healthCheck => healthCheck.Tags.Contains("sample")
});

Přizpůsobení stavového kódu HTTP

Slouží ResultStatusCodes k přizpůsobení mapování stavu na stavové kódy HTTP. Následující StatusCodes přiřazení jsou výchozí hodnoty používané middlewarem. Změňte hodnoty stavového kódu tak, aby splňovaly vaše požadavky:

app.MapHealthChecks("/healthz", new HealthCheckOptions
{
    ResultStatusCodes =
    {
        [HealthStatus.Healthy] = StatusCodes.Status200OK,
        [HealthStatus.Degraded] = StatusCodes.Status200OK,
        [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
    }
});

Potlačení hlaviček mezipaměti

AllowCachingResponses určuje, zda middleware kontroly stavu přidává hlavičky HTTP do odpovědi sondy, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je false hodnota (výchozí), middleware nastaví nebo přepíše Cache-ControlExpires, a Pragma hlavičky, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je truehodnota, middleware nezmění hlavičky mezipaměti odpovědi:

app.MapHealthChecks("/healthz", new HealthCheckOptions
{
    AllowCachingResponses = true
});

Přizpůsobení výstupu

Pokud chcete přizpůsobit výstup sestavy kontrol stavu, nastavte HealthCheckOptions.ResponseWriter vlastnost na delegáta, který zapisuje odpověď:

app.MapHealthChecks("/healthz", new HealthCheckOptions
{
    ResponseWriter = WriteResponse
});

Výchozí delegát zapíše minimální odpověď prostého textu s řetězcovou hodnotou HealthReport.Status. Následující vlastní delegát vypíše vlastní JSodpověď ON pomocí System.Text.Json:

private static Task WriteResponse(HttpContext context, HealthReport healthReport)
{
    context.Response.ContentType = "application/json; charset=utf-8";

    var options = new JsonWriterOptions { Indented = true };

    using var memoryStream = new MemoryStream();
    using (var jsonWriter = new Utf8JsonWriter(memoryStream, options))
    {
        jsonWriter.WriteStartObject();
        jsonWriter.WriteString("status", healthReport.Status.ToString());
        jsonWriter.WriteStartObject("results");

        foreach (var healthReportEntry in healthReport.Entries)
        {
            jsonWriter.WriteStartObject(healthReportEntry.Key);
            jsonWriter.WriteString("status",
                healthReportEntry.Value.Status.ToString());
            jsonWriter.WriteString("description",
                healthReportEntry.Value.Description);
            jsonWriter.WriteStartObject("data");

            foreach (var item in healthReportEntry.Value.Data)
            {
                jsonWriter.WritePropertyName(item.Key);

                JsonSerializer.Serialize(jsonWriter, item.Value,
                    item.Value?.GetType() ?? typeof(object));
            }

            jsonWriter.WriteEndObject();
            jsonWriter.WriteEndObject();
        }

        jsonWriter.WriteEndObject();
        jsonWriter.WriteEndObject();
    }

    return context.Response.WriteAsync(
        Encoding.UTF8.GetString(memoryStream.ToArray()));
}

Rozhraní API pro kontroly stavu neposkytuje integrovanou podporu složitých JSformátů on return, protože formát je specifický pro váš výběr monitorovacího systému. Podle potřeby upravte odpověď v předchozích příkladech. Další informace o JSpři serializaci pomocí System.Text.Json, naleznete v tématu Jak serializovat a deserializovat JSON v .NET.

Sonda databáze

Kontrola stavu může zadat databázový dotaz, který se má spustit jako logický test, který indikuje, jestli databáze normálně reaguje.

AspNetCore.Diagnostics.HealthChecks– knihovna kontroly stavu pro aplikace ASP.NET Core obsahuje kontrolu stavu, která se spouští v databázi SQL Serveru. AspNetCore.Diagnostics.HealthChecksSELECT 1 spustí dotaz na databázi, aby potvrdil, že připojení k databázi je v pořádku.

Upozorňující

Při kontrole připojení k databázi s dotazem zvolte dotaz, který se rychle vrátí. Přístup k dotazům riskuje přetížení databáze a snížení výkonu. Ve většině případů není spuštění testovacího dotazu nutné. Stačí pouze úspěšné připojení k databázi. Pokud zjistíte, že je nutné spustit dotaz, zvolte jednoduchý dotaz SELECT, například SELECT 1.

Pokud chcete použít tuto kontrolu stavu SQL Serveru, uveďte odkaz na AspNetCore.HealthChecks.SqlServer balíček NuGet. Následující příklad zaregistruje kontrolu stavu SQL Serveru:

builder.Services.AddHealthChecks()
    .AddSqlServer(
        builder.Configuration.GetConnectionString("DefaultConnection"));

Poznámka:

AspNetCore.Diagnostics.HealthChecks není udržována ani podporována společností Microsoft.

Sonda Entity Framework Core DbContext

Kontrola DbContext potvrzuje, že aplikace může komunikovat s databází nakonfigurovanou pro aplikaci EF CoreDbContext. Kontrola je podporovaná DbContext v aplikacích, které:

AddDbContextCheckzaregistruje kontrolu stavu pro DbContext Metoda DbContext je zadána jako TContext. K dispozici je přetížení ke konfiguraci stavu selhání, značek a vlastního testovacího dotazu.

Standardně:

  • EF CoreCanConnectAsync Volání DbContextHealthCheck metody. Můžete přizpůsobit, jakou operaci se spustí při kontrole stavu pomocí AddDbContextCheck přetížení metod.
  • Název kontroly stavu je název TContext typu.

Následující příklad zaregistruje a DbContext přidružené DbContextHealthCheck:

builder.Services.AddDbContext<SampleDbContext>(options =>
    options.UseSqlServer(
        builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddHealthChecks()
    .AddDbContextCheck<SampleDbContext>();

Samostatné testy připravenosti a aktivity

V některých scénářích hostování se k rozlišení dvou stavů aplikace používá pár kontrol stavu:

  • Připravenost označuje, jestli aplikace běží normálně, ale není připravená přijímat žádosti.
  • Liveness označuje, jestli se aplikace chybově ukončila a musí se restartovat.

Představte si následující příklad: Aplikace musí stáhnout velký konfigurační soubor, než bude připraven zpracovávat požadavky. Nechceme, aby se aplikace restartovala, pokud se počáteční stahování nezdaří, protože aplikace může několikrát zkusit stáhnout soubor znovu. K popisu aktivity procesu používáme sondu živé aktivity, nespustíme žádné další kontroly. Chceme také zabránit tomu, aby se žádosti odesílaly do aplikace před úspěšným stažením konfiguračního souboru. Sondu připravenosti použijeme k označení stavu "nepřipraveno", dokud stahování nebude úspěšné a aplikace bude připravená přijímat žádosti.

Následující úloha na pozadí simuluje proces spuštění, který trvá přibližně 15 sekund. Po dokončení nastaví úloha StartupHealthCheck.StartupCompleted vlastnost na true:

public class StartupBackgroundService : BackgroundService
{
    private readonly StartupHealthCheck _healthCheck;

    public StartupBackgroundService(StartupHealthCheck healthCheck)
        => _healthCheck = healthCheck;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        // Simulate the effect of a long-running task.
        await Task.Delay(TimeSpan.FromSeconds(15), stoppingToken);

        _healthCheck.StartupCompleted = true;
    }
}

StartupHealthCheck Hlásí dokončení dlouhotrvající spouštěcí úlohy a zveřejňuje StartupCompleted vlastnost, která se nastaví službou na pozadí:

public class StartupHealthCheck : IHealthCheck
{
    private volatile bool _isReady;

    public bool StartupCompleted
    {
        get => _isReady;
        set => _isReady = value;
    }

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        if (StartupCompleted)
        {
            return Task.FromResult(HealthCheckResult.Healthy("The startup task has completed."));
        }

        return Task.FromResult(HealthCheckResult.Unhealthy("That startup task is still running."));
    }
}

Kontrola stavu je zaregistrovaná AddCheckProgram.cs společně s hostovanými službami. Vzhledem k tomu, že hostovaná služba musí nastavit vlastnost kontroly stavu, je kontrola stavu také zaregistrována v kontejneru služby jako singleton:

builder.Services.AddHostedService<StartupBackgroundService>();
builder.Services.AddSingleton<StartupHealthCheck>();

builder.Services.AddHealthChecks()
    .AddCheck<StartupHealthCheck>(
        "Startup",
        tags: new[] { "ready" });

Pokud chcete vytvořit dva různé koncové body kontroly stavu, volejte MapHealthChecks dvakrát:

app.MapHealthChecks("/healthz/ready", new HealthCheckOptions
{
    Predicate = healthCheck => healthCheck.Tags.Contains("ready")
});

app.MapHealthChecks("/healthz/live", new HealthCheckOptions
{
    Predicate = _ => false
});

Předchozí příklad vytvoří následující koncové body kontroly stavu:

  • /healthz/ready pro kontrolu připravenosti. Kontrola připravenosti filtruje kontroly stavu na ty, které jsou označené ready.
  • /healthz/live pro kontrolu živého života. Kontrola aktivity filtruje všechny kontroly stavu vrácením false delegáta HealthCheckOptions.Predicate . Další informace o filtrování kontrol stavu najdete v tématu Filtrování kontrol stavu v tomto článku.

Před dokončením /healthz/ready spouštěcí úlohy koncový bod hlásí Unhealthy stav. Po dokončení spouštěcí úlohy tento koncový bod hlásí Healthy stav. Koncový /healthz/live bod vyloučí všechny kontroly a hlásí Healthy stav všech volání.

Příklad Kubernetes

Použití samostatných kontrol připravenosti a aktivity je užitečné v prostředí, jako je Kubernetes. V Kubernetes může být aplikace nutná ke spouštění časově náročných spouštěcích prací před přijetím požadavků, jako je například test dostupnosti podkladové databáze. Použití samostatných kontrol umožňuje orchestrátoru rozlišit, jestli aplikace funguje, ale ještě není připravená nebo jestli se aplikaci nepodařilo spustit. Další informace o testech připravenosti a aktivity v Kubernetes najdete v dokumentaci ke konfiguraci testů živé aktivity a připravenosti v Kubernetes.

Následující příklad ukazuje konfiguraci sondy připravenosti Kubernetes:

spec:
  template:
  spec:
    readinessProbe:
      # an http probe
      httpGet:
        path: /healthz/ready
        port: 80
      # length of time to wait for a pod to initialize
      # after pod startup, before applying health checking
      initialDelaySeconds: 30
      timeoutSeconds: 1
    ports:
      - containerPort: 80

Distribuce knihovny kontroly stavu

Distribuce kontroly stavu jako knihovny:

  1. Napište kontrolu stavu, která implementuje IHealthCheck rozhraní jako samostatnou třídu. Třída se může spoléhat na injektáž závislostí (DI), aktivaci typu a pojmenované možnosti pro přístup ke konfiguračním datům.

  2. Napište metodu rozšíření s parametry, které spotřebová aplikace volá ve své Program.cs metodě. Podívejte se na následující příklad kontroly stavu, která přijímá arg1 parametry konstruktoru a arg2 jako parametry:

    public SampleHealthCheckWithArgs(int arg1, string arg2)
        => (_arg1, _arg2) = (arg1, arg2);
    

    Předchozí podpis označuje, že kontrola stavu vyžaduje vlastní data ke zpracování logiky sondy kontroly stavu. Data se poskytují delegátu použitému k vytvoření instance kontroly stavu při registraci kontroly stavu v metodě rozšíření. V následujícím příkladu volající určuje:

    • arg1: Celočíselná datová hodnota pro kontrolu stavu.
    • arg2: Řetězcový argument pro kontrolu stavu.
    • name: Volitelný název kontroly stavu. Pokud nullse použije výchozí hodnota.
    • failureStatus: Nepovinný údaj HealthStatus, který je hlášen pro stav selhání. Pokud nullse použije , HealthStatus.Unhealthy použije se.
    • tags: Volitelná IEnumerable<string> kolekce značek.
    public static class SampleHealthCheckBuilderExtensions
    {
        private const string DefaultName = "Sample";
    
        public static IHealthChecksBuilder AddSampleHealthCheck(
            this IHealthChecksBuilder healthChecksBuilder,
            int arg1,
            string arg2,
            string? name = null,
            HealthStatus? failureStatus = null,
            IEnumerable<string>? tags = default)
        {
            return healthChecksBuilder.Add(
                new HealthCheckRegistration(
                    name ?? DefaultName,
                    _ => new SampleHealthCheckWithArgs(arg1, arg2),
                    failureStatus,
                    tags));
        }
    }
    

Kontrola stavu – Vydavatel

IHealthCheckPublisher Po přidání do kontejneru služby systém kontroly stavu pravidelně provádí kontroly stavu a volání PublishAsync s výsledkem. Tento proces je užitečný ve scénáři systému monitorování stavu založeného na nabízených oznámeních, který očekává, že každý proces bude pravidelně volat monitorovací systém, aby zjistil stav.

HealthCheckPublisherOptions umožňuje nastavit:

  • Delay: Počáteční prodleva použitá po spuštění aplikace před spuštěním IHealthCheckPublisher instancí. Zpoždění se použije jednou při spuštění a nevztahuje se na pozdější iterace. Výchozí hodnota je pět sekund.
  • Period: Období IHealthCheckPublisher provádění. Výchozí hodnota je 30 sekund.
  • Predicate: Pokud Predicate je null (výchozí), spustí služba vydavatele kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která filtruje sadu kontrol. Predikát se vyhodnocuje každé období.
  • Timeout: Časový limit pro provádění kontrol stavu pro všechny IHealthCheckPublisher instance. Slouží InfiniteTimeSpan ke spuštění bez časového limitu. Výchozí hodnota je 30 sekund.

Následující příklad ukazuje rozložení vydavatele stavu:

public class SampleHealthCheckPublisher : IHealthCheckPublisher
{
    public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
    {
        if (report.Status == HealthStatus.Healthy)
        {
            // ...
        }
        else
        {
            // ...
        }

        return Task.CompletedTask;
    }
}

Třída HealthCheckPublisherOptions poskytuje vlastnosti pro konfiguraci chování vydavatele kontroly stavu.

Následující příklad zaregistruje vydavatele kontroly stavu jako singleton a nakonfiguruje HealthCheckPublisherOptions:

builder.Services.Configure<HealthCheckPublisherOptions>(options =>
{
    options.Delay = TimeSpan.FromSeconds(2);
    options.Predicate = healthCheck => healthCheck.Tags.Contains("sample");
});

builder.Services.AddSingleton<IHealthCheckPublisher, SampleHealthCheckPublisher>();

Poznámka:

AspNetCore.Diagnostics.HealthCheckszahrnuje vydavatele pro několik systémů, včetně aplikačních Přehledy.

AspNetCore.Diagnostics.HealthChecks není udržována ani podporována společností Microsoft.

Injektáž závislostí a kontroly stavu

Injektáž závislostí je možné použít ke spotřebování instance konkrétní Type instance uvnitř třídy kontroly stavu. Injektáž závislostí může být užitečná pro vložení možností nebo globální konfigurace do kontroly stavu. Použití injektáže závislostí není běžným scénářem konfigurace kontrol stavu. Každá kontrola stavu je obvykle zcela specifická pro skutečný test a je nakonfigurovaná pomocí IHealthChecksBuilder rozšiřujících metod.

Následující příklad ukazuje ukázkovou kontrolu stavu, která načte objekt konfigurace prostřednictvím injektáže závislostí:

public class SampleHealthCheckWithDI : IHealthCheck
{
    private readonly SampleHealthCheckWithDiConfig _config;

    public SampleHealthCheckWithDI(SampleHealthCheckWithDiConfig config)
        => _config = config;

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        var isHealthy = true;

        // use _config ...

        if (isHealthy)
        {
            return Task.FromResult(
                HealthCheckResult.Healthy("A healthy result."));
        }

        return Task.FromResult(
            new HealthCheckResult(
                context.Registration.FailureStatus, "An unhealthy result."));
    }
}

Do SampleHealthCheckWithDiConfig kontejneru služby je potřeba přidat kontrolu stavu:

builder.Services.AddSingleton<SampleHealthCheckWithDiConfig>(new SampleHealthCheckWithDiConfig
{
    BaseUriToCheck = new Uri("https://sample.contoso.com/api/")
});
builder.Services.AddHealthChecks()
    .AddCheck<SampleHealthCheckWithDI>(
        "With Dependency Injection",
        tags: new[] { "inject" });

UseHealthChecks vs. MapHealthChecks

Existují dva způsoby zpřístupnění kontrol stavu volajícím:

  • UseHealthChecks zaregistruje middleware pro zpracování žádostí o kontroly stavu v kanálu middlewaru.
  • MapHealthChecks zaregistruje koncový bod kontroly stavu. Koncový bod se porovná a spustí spolu s dalšími koncovými body v aplikaci.

Výhodou použití MapHealthChecks oproti UseHealthChecks tomu je možnost používat middleware s podporou koncových bodů, jako je autorizace, a mít větší jemně odstupňovanou kontrolu nad odpovídajícími zásadami. Hlavní výhodou použití UseHealthChecks je MapHealthChecks řízení přesně toho, kde se kontroly stavu spouští v kanálu middlewaru.

UseHealthChecks:

  • Ukončí kanál, když požadavek odpovídá koncovému bodu kontroly stavu. Zkratování je často žádoucí, protože zabraňuje zbytečné práci, jako je protokolování a další middleware.
  • Primárně se používá ke konfiguraci middlewaru kontroly stavu v kanálu.
  • Může odpovídat jakékoli cestě na portu s nebo prázdným nullPathString. Umožňuje provést kontrolu stavu u všech požadavků provedených na zadaném portu.
  • Zdrojový kód

MapHealthChecks Umožňuje:

  • Mapování konkrétních tras nebo koncových bodů pro kontroly stavu
  • Přizpůsobení adresy URL nebo cesty, kde je koncový bod kontroly stavu přístupný.
  • Mapování několika koncových bodů kontroly stavu s různými trasami nebo konfiguracemi Podpora více koncových bodů:
    • Umožňuje samostatné koncové body pro různé typy kontrol stavu nebo součástí.
    • Používá se k rozlišení různých aspektů stavu aplikace nebo použití konkrétních konfigurací na podmnožinu kontrol stavu.
  • Zdrojový kód

Další materiály

Poznámka:

Tento článek byl částečně vytvořen pomocí umělé inteligence. Před zveřejněním autor obsah zkontroloval a podle potřeby upravil. Viz Naše zásady pro používání obsahu generovaného AI v Microsoft Learn.