Kontroly stavu v ASP.NET Core

Od Glenn Condron a Juergen Gutsch

Note

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

Warning

Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální verzi najdete ve verzi .NET 10 tohoto článku.

ASP.NET Core nabízí middleware pro kontroly stavu a knihovny pro hlášení stavu komponent infrastruktury aplikace.

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 vyrovnavače 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 stanoví, jaké typy testů 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 vyvolá middleware pro kontroly stavu, aby na koncovém bodu URL vracel odpověď o stavu. 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 zdravou, 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 HealthStatus, HealthStatus.Healthy, HealthStatus.Degraded, nebo HealthStatus.Unhealthy.

Zaregistrujte služby zdravotní kontroly v AddHealthChecks v Program.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();

DockerHEALTHCHECK

Docker obsahuje integrovanou HEALTHCHECK direktivu, kterou můžete použít ke kontrole stavu aplikace, která používá základní konfiguraci kontroly stavu:

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

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 můžete ho přidat instalací požadovaného balíčku do souboru Dockerfile. Kontejnery, které používají obrázky založené na Alpine Linuxu, mohou použít wget namísto curl.

Vytvořit kontroly stavu

Vytvořte kontroly stavu prováděním rozhraní IHealthCheck. 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. Viz část Možnosti kontroly stavu . HealthCheckResult může také vracet volitelné klíče a hodnoty.

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 s nastaveným HealthReportEntry.Status na FailureStatus. Tento stav je definován AddCheck (viz část Registrace služeb kontroly stavu) a obsahuje vnitřní výjimku, která způsobila selhání kontroly. Description je 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");

AddCheck Přetížení zobrazené v následujícím příkladu nastaví stav selhání (HealthStatus), který má být hlášen, když kontrola stavu indikuje 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 prosazován aplikací, když dojde k selhání kontroly stavu, pokud implementace kontroly stavu respektuje toto 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í funkce AddTypeActivatedCheck pro předání argumentů implementaci kontroly stavu V následujícím příkladu přijímá kontrola stavu aktivovaná pomocí typu celé číslo a řetězec ve svém 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 s celým číslem a řetězcem předanými jako argumenty.

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

Použití kontrol stavu při směrování

V Program.cs zavolejte v MapHealthChecks na sestavení koncového bodu pomocí adresy URL koncového bodu nebo relativní cesty:

app.MapHealthChecks("/healthz");

Vyžadovat hostitele (server)

Použijte RequireHost k zadání jednoho nebo více povolených hostitelů pro koncový bod kontroly stavu. Místo punycode pro hostitele používejte Unicode a můžete zahrnout port. Pokud kolekci nezadáte, přijme se jakýkoli 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. Obvykle tento přístup použijte v prostředí kontejneru k zveřejnění portu pro monitorovací služby:

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

Warning

Rozhraní API, které závisí na Host header, jako například HttpRequest.Host a RequireHost, jsou náchylná k potenciálnímu falšování ze strany klientů.

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

Zavolejte RequireAuthorization, aby se na koncovém bodu požadavků na kontrolu stavu spustil autorizační middleware. 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ů kontroly 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 zdraví:

Kontrola kondice filtrů

Ve výchozím nastavení middleware pro kontroly stavu spustí všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která ve volbě Predicate vrátí hodnotu typu Boolean.

Následující příklad filtruje kontroly stavu, aby se spustily pouze ty, které jsou označené sample .

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

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

Použijte ResultStatusCodes k úpravě mapování stavu zdraví 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, jestli middleware kontroly stavu přidá hlavičky HTTP do odpovědi sondy, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je výchozí hodnota false, middleware nastaví nebo přepíše hlavičky Cache-Control, Expires a Pragma, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je hodnota true, 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 zprávy o kontrolách zdraví, nastavte HealthCheckOptions.ResponseWriter vlastnost na delegáta, který vykresluje 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í odpověď JSON 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 návratových formátů JSON, 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 serializaci JSON pomocí System.Text.Json, naleznete v tématu Jak serializovat a deserializovat JSON v .NET.

Test 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.HealthChecks SELECT 1 spustí dotaz na databázi, aby potvrdil, že připojení k databázi je v pořádku.

Warning

Při kontrole připojení k databázi pomocí dotazu 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);

Note

Microsoft neudržuje ani nepodporuje AspNetCore.Diagnostics.HealthChecks.

Entity Framework Core DbContext test

Kontrola DbContext potvrzuje, že aplikace může komunikovat s databází nakonfigurovanou pro aplikaci EF CoreDbContext. Aplikace, které podporují DbContext kontrolu:

AddDbContextCheckzaregistruje kontrolu stavu pro DbContext DbContext je dodáno metodě jako TContext. Je dostupné přetížení funkce pro konfiguraci stavu selhání, značek a vlastního testovacího dotazu.

Ve výchozím nastavení:

  • DbContextHealthCheck volá metodu EF Core objektu CanConnectAsync. Můžete přizpůsobit, jaká operace se spustí při kontrole stavu pomocí přetížení metody AddDbContextCheck.
  • Název kontroly stavu je název TContext typu.

Následující příklad zaregistruje DbContext a spojený DbContextHealthCheck:

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

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

Samostatné sondy připravenosti a živosti

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

  • Připravenost označuje, jestli aplikace běží normálně, ale není připravená přijímat žádosti.
  • Liveness označuje, jestli aplikace spadla 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. Pokud se počáteční stahování nezdaří, nechcete aplikaci restartovat, protože aplikace může několikrát zkusit stáhnout soubor znovu. Použijte sondu živé aktivity k popisu aktivity procesu, nespustí se žádné další kontroly. Chcete také zabránit tomu, aby se požadavky odesílaly do aplikace, než bude stahování konfiguračního souboru úspěšné. Pomocí testu připravenosti označte stav "není připravený", 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, kterou služba na pozadí nastaví:

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

Zaregistrujte zdravotní kontrolu s AddCheck v Program.cs spolu s hostovanou službou. Vzhledem k tomu, že hostovaná služba nastaví vlastnost kontroly stavu, zaregistrujte také kontrolu stavu v kontejneru služby jako jednoton:

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 živosti. Kontrola živosti filtruje všechny zdravotní kontroly vrácením false v delegátu HealthCheckOptions.Predicate. Další informace o filtrování kontrol stavu naleznete v části Filtrování kontrol stavu v tomto článku.

Před dokončením spouštěcí úlohy /healthz/ready koncový bod hlásí stav Unhealthy. 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 Kubernetes. V Kubernetes může aplikace potřebovat spustit časově náročnou spouštěcí práci, aby mohla přijímat požadavky, jako je například test dostupnosti podkladové databáze. Pomocí samostatných kontrol může orchestrátor zjistit, 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 zdravotní kontroly

Pro distribuci 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 a arg2 jako parametry konstruktoru.

    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 jsou poskytována delegátu použitému k vytvoření instance kontroly stavu, když je kontrola stavu registrována pomocí rozšiřující metody. 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 zdravotní kontroly. Pokud nullse použije výchozí hodnota.
    • failureStatus: Nepovinný prvek HealthStatus, který se hlásí pro stav selhání. Pokud se použije null, použije se HealthStatus.Unhealthy.
    • 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

Po přidání IHealthCheckPublisher do kontejneru služby systém kontroly stavu pravidelně provádí kontroly stavu a volá funkci 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 po spuštění aplikace před spuštěním IHealthCheckPublisher instancí. Zpoždění nastane při spuštění jednou a nevztahuje se na pozdější iterace. Výchozí hodnota je pět sekund.
  • Period: Doba výkonu IHealthCheckPublisher. Výchozí hodnota je 30 sekund.
  • Predicate: Pokud Predicate je null (výchozí), služba publikování zdravotních kontrol spustí všechny registrované zdravotní kontroly. 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. Použijte InfiniteTimeSpan ke spuštění bez časového limitu. Výchozí hodnota je 30 sekund.

Následující příklad ukazuje uspořádání zdravotnického vydavatele:

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 zdravotních kontrol.

Následující příklad registruje publikátora zdravotní kontroly jako singleton a konfiguruje 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ě Application Insights.
  • Není udržováno nebo podporováno společností Microsoft.

Jednotlivé kontroly stavu

Můžete nastavit Delay a Period na každém HealthCheckRegistration jednotlivě. Tyto hodnoty nastavte, pokud chcete spustit některé kontroly stavu 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í dependency injection není ne běžným scénářem konfigurace kontrol stavu. Každá kontrola stavu je obvykle velmi specifická pro daný test a je nakonfigurována pomocí rozšiřujících metod IHealthChecksBuilder.

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 kontejneru služby je potřeba přidat SampleHealthCheckWithDiConfig a 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

Kontroly stavu můžete zpřístupnit volajícím dvěma způsoby:

  • UseHealthChecks registruje middleware pro zpracování požadavků na kontroly zdraví v řetězci middlewaru.
  • MapHealthChecks zaregistruje koncový bod zdravotních kontrol. Koncový bod je identifikován a spuštěn stejně jako další koncové body v aplikaci.

Místo MapHealthChecks můžete použít UseHealthChecks, což umožňuje používat middleware s podporou koncových bodů, jako je autorizace, a získat jemnější kontrolu nad politikou sladění. Použitím UseHealthChecks místo MapHealthChecks, řídíte přesně to, kde se zdravotní kontroly spouští v kanálu middlewaru.

UseHealthChecks:

  • Ukončí pipeline, když požadavek odpovídá koncovému bodu kontroly stavu. Krátké spojení je často žádoucí, protože zabraňuje zbytečné práci, jako je protokolování a další middleware.
  • Používá se především ke konfiguraci middlewaru kontroly stavu v pipeline.
  • Může odpovídat jakékoli cestě na portu s null nebo prázdným PathString. Umožňuje provést health check u každého požadavku 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 se zkratem 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

Dodatečné zdroje

Note

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í middleware a knihovny pro kontroly stavu, které slouží k vytváření sestav o stavu komponent infrastruktury aplikace.

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 vyrovnavače 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.

Prerequisites

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 stanoví, jaké typy testů 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ázového připojení kontroluje kondici 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:

Note

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 kontrol stavu a zavolá middleware kontrol stavu, který vrací odpověď o stavu na koncovém bodu URL. 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 zdravou, 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 a označuje buď stav HealthStatus.Healthy, HealthStatus.Degraded, nebo HealthStatus.Unhealthy.

Zaregistrujte služby zdravotní kontroly v AddHealthChecks v Startup.ConfigureServices. Vytvořte koncový bod kontroly stavu voláním MapHealthChecks v Startup.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

Vytvořit kontroly stavu

Kontroly zdraví se vytvářejí implementací rozhraní IHealthCheck. 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é klíče a hodnoty.

Následující ExampleHealthCheck třída demonstruje rozložení kontroly zdraví. Logika kontroly stavu je umístěna v metodě CheckHealthAsync. 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 vyvolá výjimku během kontroly, vrátí se nová HealthReportEntry s její HealthReportEntry.Status nastavenou na FailureStatus, což je definováno v AddCheck (viz část Registrace služeb kontroly stavu) a obsahuje vnitřní výjimku, která původně způsobila chybu kontroly. Description je nastaven na zprávu výjimky.

Registrace služeb kontroly stavu

Typ ExampleHealthCheck se přidá ke službám kontroly stavu s AddCheck v Startup.ConfigureServices.

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

AddCheck Přetížení zobrazené v následujícím příkladu nastaví stav selhání (HealthStatus), který má být hlášen, když kontrola stavu indikuje 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 prosazován aplikací, když dojde k selhání kontroly stavu, pokud implementace kontroly stavu respektuje toto nastavení.

Značky lze použít k filtraci kontrol stavu (popsáno dále v části Filtr kontrol stavu).

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í funkce 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 s celým číslem a řetězcem, které jsou předány implementaci:

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

Použití kontrol stavu při směrování

V Startup.Configure zavolejte v MapHealthChecks na sestavení koncového bodu pomocí adresy URL koncového bodu nebo relativní cesty:

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

Vyžadovat hostitele (server)

Použijte RequireHost k zadání jednoho nebo více povolených hostitelů pro koncový bod kontroly stavu. Hostitelé by měli používat kódování Unicode místo punycode a mohou obsahovat síťový port. Pokud není zadána žádná kolekce, přijímá se libovolný hostitel.

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

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

Vyžadovat autorizaci

Zavolejte RequireAuthorization, aby se pro koncový bod požadavku na kontrolu stavu spustil autorizační middleware. 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ě v prohlížeči 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áta pro tvorbu zásad CORSCorsPolicyBuilder nebo název politiky. 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 zdraví:

Kontrola kondice filtrů

Ve výchozím nastavení middleware kontrol stavu spustí všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která ve volbě Predicate vrátí hodnotu typu Boolean. V následujícím příkladu je kontrola stavu Bar vyfilterována podle její značky (bar_tag) v podmíněném příkazu funkce, kde true je vráceno pouze tehdy, pokud se vlastnost Tags kontroly stavu shoduje s foo_tag nebo s 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" });

Ve Startup.ConfigurePredicate odstraní kontrolu stavu 'Bar'. 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

Použijte ResultStatusCodes k úpravě mapování stavu zdraví 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 pro kontroly stavu přidá do odpovědi na sondu hlavičky protokolu HTTP, aby zabránil ukládání odpovědi do mezipaměti. Pokud je výchozí hodnota false, middleware nastaví nebo přepíše hlavičky Cache-Control, Expires a Pragma, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je hodnota true, 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 v Startup.Configure možnost HealthCheckOptions.ResponseWriter na delegáta pro zapsání 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íšou vlastní odpověď ve formátu JSON.

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 preprocesoru v , abyste mohli povolit verzi pro .

Rozhraní API pro kontroly stavu neposkytuje integrovanou podporu složitých návratových formátů JSON, 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 serializaci JSON pomocí System.Text.Json, naleznete v tématu Jak serializovat a deserializovat JSON v .NET.

Test 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.HealthChecks knihovnu zdravotní kontroly pro aplikace ASP.NET Core ke spuštění zdravotní kontroly v databázi SQL Serveru. AspNetCore.Diagnostics.HealthChecks SELECT 1 spustí dotaz na databázi, aby potvrdil, že připojení k databázi je v pořádku.

Warning

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 balíček AspNetCore.HealthChecks.SqlServer.

Zadejte platný řetězec připojení k databázi do souboru appsettings.json ukázkové aplikace. 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 zdravotní kontroly v AddHealthChecks v Startup.ConfigureServices. Ukázková aplikace volá metodu AddSqlServer s připojovacím řetězcem databáze (DbHealthStartup.cs):

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

Koncový bod kontroly stavu se vytvoří voláním MapHealthChecks v Startup.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

Note

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

Entity Framework Core DbContext test

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

AddDbContextCheck<TContext>zaregistruje kontrolu stavu pro DbContext DbContext je dodáváno jako TContext metodě. Je dostupné přetížení funkce pro konfiguraci stavu selhání, značek a vlastního testovacího dotazu.

Ve výchozím nastavení:

  • DbContextHealthCheck volá metodu EF Core objektu CanConnectAsync. Můžete přizpůsobit, jaká operace se spustí při kontrole stavu, a to pomocí přetížení metod AddDbContextCheck.
  • Název kontroly stavu je název TContext typu.

V ukázkové aplikaci je AppDbContext poskytován pro AddDbContextCheck a zaregistrován 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 MapHealthChecks v Startup.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ím řetězcem 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 aplikace odeslání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.

Odešlete požadavek na koncový bod /health. 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.

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

Unhealthy

Samostatné sondy připravenosti a živosti

V některých scénářích hostování se používá dvojice zdravotních kontrol k rozlišení dvou stavů aplikace.

  • Připravenost označuje, jestli aplikace běží normálně, ale není připravená přijímat žádosti.
  • Liveness označuje, jestli aplikace spadla 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 liveness procesu používáme liveness probe, žádné další kontroly nejsou prováděny. 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 hostovanou službou (Services/StartupHostedService). Na závěr úkolu je StartupHostedServiceHealthCheck.StartupTaskCompleted nastaveno na 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 zaregistrována u AddCheck v Startup.ConfigureServices společně s hostovanou službou. 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 podle značky ready.
  • /health/live pro kontrolu živosti. Kontrola liveness filtruje StartupHostedServiceHealthCheck vrácením false v rámci HealthCheckOptions.Predicate (další informace najdete v sekci 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 během 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ří modul publikace kontroly stavu (IHealthCheckPublisher implementaci), který spustí první kontrolu připravenosti s dvousekundovým zpožděním. Další informace naleznete v části Health Check Publisher.

Příklad Kubernetes

Použití samostatných kontrol připravenosti a aktivity je užitečné v prostředí, jako 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). HealthCheckResult obsahuje informace o garbage collectoru (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 zdravotní kontroly v AddHealthChecks v Startup.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 ukázkové aplikaci CustomWriterStartup.cs:

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

Koncový bod kontroly stavu se vytvoří voláním MapHealthChecksStartup.Configure. Delegát WriteResponse je poskytnut vlastnosti ResponseWriter pro generování vlastní JSON odpovědi při provedení kontroly stavu.

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

Delegát WriteResponse formátuje objekt CompositeHealthCheckResult JSON a vrátí výstup JSON 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

Note

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

Volání RequireHost na MapHealthChecks se vzorem URL, který určí port a omezí požadavky na kontrolu stavu na tento 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í poskytovatele konfigurace proměnných prostředí. Port se nastaví v launchSettings.json souboru a zprostředkovateli konfigurace se předá 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 zdravotní kontroly v AddHealthChecks v Startup.ConfigureServices. Vytvořte koncový bod kontroly stavu voláním MapHealthChecks v Startup.Configure.

V ukázkové aplikaci volání RequireHost na koncovém bodu v Startup.Configure specifikuje port pro správu z konfigurace.

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

Koncové body se vytvoří v ukázkové aplikaci v Startup.Configure. 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
    });
}

Note

V ukázkové aplikaci se můžete vyhnout vytváření launchSettings.json souboru nastavením portu pro správu explicitně v kódu. Kde je Program.cs vytvořen, přidejte volání na HostBuilder 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 zdravotní kontroly

Pro distribuci 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 kontrol stavu CheckHealthAsync:

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

    Když dojde k události AccessViolationException, vrátí se FailureStatus spolu s HealthCheckResult, což uživatelům umožňuje 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í signaturu 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 jsou poskytována delegátu použitému k vytvoření instance kontroly stavu, když je kontrola stavu registrována pomocí rozšiřující metody. V následujícím příkladu volající určuje volitelné:

    • název kontroly stavu (name). Pokud se použije null, použije se example_health_check.
    • řetězcový datový bod pro kontrolu stavu (data1).
    • celočíselný datový bod pro kontrolu stavu (data2). Pokud se použije null, použije se 1.
    • stav selhání (HealthStatus). Výchozí hodnota je null. Pokud je null nahlášen jako 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

Po přidání IHealthCheckPublisher do kontejneru služby systém kontroly stavu pravidelně provádí kontroly stavu a volá funkci 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 umožňují 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 následné iterace. Výchozí hodnota je pět sekund.
  • Period: Doba výkonu IHealthCheckPublisher. Výchozí hodnota je 30 sekund.
  • Predicate: Pokud Predicate je null (výchozí), služba publikování zdravotních kontrol spustí všechny registrované zdravotní kontroly. 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. Použijte InfiniteTimeSpan ke spuštění bez časového limitu. Výchozí hodnota je 30 sekund.

V ukázkové aplikaci je implementace ReadinessPublisherIHealthCheckPublisher. Stav kontroly se protokoluje pro každou kontrolu na úrovni protokolování:

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 ukázkové aplikace LivenessProbeStartupStartupHostedService má kontrola připravenosti zpoždění spuštění dvě sekundy a provádí kontrolu každých 30 sekund. K aktivaci IHealthCheckPublisher implementace ukázka registruje ReadinessPublisher jako singletonní službu v kontejneru injekce 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>();

Note

AspNetCore.Diagnostics.HealthChecks zahrnuje vydavatele pro několik systémů, včetně Application Insights.

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

Omezení kontrol stavu pomocí MapWhen

Pomocí MapWhen směrujte podmíněně potrubí požadavků pro koncové body kontroly stavu.

V následujícím příkladu MapWhen rozvětví kanál požadavků tak, aby se aktivoval middleware kontroly stavu, pokud je pro koncový bod api/HealthCheck přijat 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 ASP.NET Core middleware.

ASP.NET Core nabízí middleware pro kontroly stavu a knihovny pro vykazování stavu komponent infrastruktury aplikace.

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 vyrovnavače 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.

Prerequisites

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 stanoví, jaké typy testů 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. Pro spuštění kontrol stavu pomocí Entity Framework Core přidejte odkaz na balíček Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore.

Ukázková aplikace poskytuje spouštěcí kód, který demonstruje kontroly stavu pro několik scénářů. Scénář sondy databázového připojení kontroluje kondici 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:

Note

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 vyvolá middleware kontrol stavu, aby na koncovém bodu URL odpovídal odpovědí o stavu. 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 zdravou, 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 a označuje buď stav HealthStatus.Healthy, HealthStatus.Degraded, nebo HealthStatus.Unhealthy.

Zaregistrujte služby zdravotní kontroly v AddHealthChecks v Startup.ConfigureServices. Vytvořte koncový bod kontroly stavu voláním MapHealthChecks v Startup.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

Vytvořit kontroly stavu

Kontroly zdraví se vytvářejí implementací rozhraní IHealthCheck. 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é klíče a hodnoty.

Následující ExampleHealthCheck třída demonstruje rozložení kontroly zdraví. Logika kontroly stavu je umístěna v metodě CheckHealthAsync. 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 AddCheck v Startup.ConfigureServices.

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

AddCheck Přetížení zobrazené v následujícím příkladu nastaví stav selhání (HealthStatus), který má být hlášen, když kontrola stavu indikuje 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 prosazován aplikací, když dojde k selhání kontroly stavu, pokud implementace kontroly stavu respektuje toto nastavení.

Značky lze použít k filtraci kontrol stavu (popsáno dále v části Filtr kontrol stavu).

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í funkce 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 s celým číslem a řetězcem, které jsou předány implementaci:

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

Použití kontrol stavu při směrování

V Startup.Configure zavolejte v MapHealthChecks na sestavení koncového bodu pomocí adresy URL koncového bodu nebo relativní cesty:

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

Vyžadovat hostitele (server)

Použijte RequireHost k zadání jednoho nebo více povolených hostitelů pro koncový bod kontroly stavu. Hostitelé by měli používat kódování Unicode místo punycode a mohou obsahovat síťový port. Pokud není zadána žádná kolekce, přijímá se libovolný 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ím RequireAuthorization spustíte autorizační middleware na koncovém bodu požadavku na 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ě v prohlížeči 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áta pro tvorbu zásad CORSCorsPolicyBuilder nebo název politiky. 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 zdraví:

Kontrola kondice filtrů

Ve výchozím nastavení middleware pro kontroly stavu spouští všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která ve volbě Predicate vrátí hodnotu typu Boolean. V následujícím příkladu je kontrola stavu Bar vyfilterována podle její značky (bar_tag) v podmíněném příkazu funkce, kde true je vráceno pouze tehdy, pokud se vlastnost Tags kontroly stavu shoduje s foo_tag nebo s 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" });

Ve Startup.ConfigurePredicate odstraní kontrolu stavu 'Bar'. 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

Použijte ResultStatusCodes k úpravě mapování stavu zdraví 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 pro kontroly stavu přidá do odpovědi sondy hlavičky HTTP, aby zabránil ukládání odpovědi do mezipaměti. Pokud je výchozí hodnota false, middleware nastaví nebo přepíše hlavičky Cache-Control, Expires a Pragma, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je hodnota true, 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 v Startup.Configure možnost HealthCheckOptions.ResponseWriter na delegáta pro zapsání 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íšou vlastní odpověď ve formátu JSON.

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 preprocesoru v , abyste mohli povolit verzi pro .

Rozhraní API pro kontroly stavu neposkytuje integrovanou podporu složitých návratových formátů JSON, 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 serializaci JSON pomocí System.Text.Json, naleznete v tématu Jak serializovat a deserializovat JSON v .NET.

Test 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.HealthChecks knihovnu zdravotní kontroly pro aplikace ASP.NET Core ke spuštění zdravotní kontroly v databázi SQL Serveru. AspNetCore.Diagnostics.HealthChecks SELECT 1 spustí dotaz na databázi, aby potvrdil, že připojení k databázi je v pořádku.

Warning

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 balíček AspNetCore.HealthChecks.SqlServer.

Zadejte platný řetězec připojení k databázi do souboru appsettings.json ukázkové aplikace. 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 zdravotní kontroly v AddHealthChecks v Startup.ConfigureServices. Ukázková aplikace volá metodu AddSqlServer s připojovacím řetězcem databáze (DbHealthStartup.cs):

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

Koncový bod kontroly stavu se vytvoří voláním MapHealthChecks v Startup.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

Note

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

Entity Framework Core DbContext test

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

AddDbContextCheck<TContext>zaregistruje kontrolu stavu pro DbContext DbContext je dodáváno jako TContext metodě. Je dostupné přetížení funkce pro konfiguraci stavu selhání, značek a vlastního testovacího dotazu.

Ve výchozím nastavení:

  • DbContextHealthCheck volá metodu EF Core objektu CanConnectAsync. Můžete přizpůsobit, jaká operace se spustí při kontrole stavu, a to pomocí přetížení metod AddDbContextCheck.
  • Název kontroly stavu je název TContext typu.

V ukázkové aplikaci je AppDbContext poskytován pro AddDbContextCheck a zaregistrován 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 MapHealthChecks v Startup.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ím řetězcem 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 aplikace odeslání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.

Odešlete požadavek na koncový bod /health. 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.

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

Unhealthy

Samostatné sondy připravenosti a živosti

V některých scénářích hostování se používá dvojice zdravotních kontrol k rozlišení dvou stavů aplikace.

  • Připravenost označuje, jestli aplikace běží normálně, ale není připravená přijímat žádosti.
  • Liveness označuje, jestli aplikace spadla 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 liveness procesu používáme liveness probe, žádné další kontroly nejsou prováděny. 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 hostovanou službou (Services/StartupHostedService). Na závěr úkolu je StartupHostedServiceHealthCheck.StartupTaskCompleted nastaveno na 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 zaregistrována u AddCheck v Startup.ConfigureServices společně s hostovanou službou. 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 podle značky ready.
  • /health/live pro kontrolu živosti. Kontrola liveness filtruje StartupHostedServiceHealthCheck vrácením false v rámci HealthCheckOptions.Predicate (další informace najdete v sekci 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 během 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ří modul publikace kontroly stavu (IHealthCheckPublisher implementaci), který spustí první kontrolu připravenosti s dvousekundovým zpožděním. Další informace naleznete v části Health Check Publisher.

Příklad Kubernetes

Použití samostatných kontrol připravenosti a aktivity je užitečné v prostředí, jako 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). HealthCheckResult obsahuje informace o garbage collectoru (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 zdravotní kontroly v AddHealthChecks v Startup.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 ukázkové aplikaci CustomWriterStartup.cs:

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

Koncový bod kontroly stavu se vytvoří voláním MapHealthChecksStartup.Configure. Delegát WriteResponse je poskytnut vlastnosti ResponseWriter pro generování vlastní JSON odpovědi při provedení kontroly stavu.

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

Delegát WriteResponse formátuje objekt CompositeHealthCheckResult JSON a vrátí výstup JSON 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

Note

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

Volání RequireHost na MapHealthChecks se vzorem URL, který určí port a omezí požadavky na kontrolu stavu na tento 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í poskytovatele konfigurace proměnných prostředí. Port se nastaví v launchSettings.json souboru a zprostředkovateli konfigurace se předá 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 zdravotní kontroly v AddHealthChecks v Startup.ConfigureServices. Vytvořte koncový bod kontroly stavu voláním MapHealthChecks v Startup.Configure.

V ukázkové aplikaci volání RequireHost na koncovém bodu v Startup.Configure specifikuje port pro správu z konfigurace.

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

Koncové body se vytvoří v ukázkové aplikaci v Startup.Configure. 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
    });
}

Note

V ukázkové aplikaci se můžete vyhnout vytváření launchSettings.json souboru nastavením portu pro správu explicitně v kódu. Kde je Program.cs vytvořen, přidejte volání na HostBuilder 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 zdravotní kontroly

Pro distribuci 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 kontrol stavu CheckHealthAsync:

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

    Když dojde k události AccessViolationException, vrátí se FailureStatus spolu s HealthCheckResult, což uživatelům umožňuje 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í signaturu 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 jsou poskytována delegátu použitému k vytvoření instance kontroly stavu, když je kontrola stavu registrována pomocí rozšiřující metody. V následujícím příkladu volající určuje volitelné:

    • název kontroly stavu (name). Pokud se použije null, použije se example_health_check.
    • řetězcový datový bod pro kontrolu stavu (data1).
    • celočíselný datový bod pro kontrolu stavu (data2). Pokud se použije null, použije se 1.
    • stav selhání (HealthStatus). Výchozí hodnota je null. Pokud je null nahlášen jako 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

Po přidání IHealthCheckPublisher do kontejneru služby systém kontroly stavu pravidelně provádí kontroly stavu a volá funkci 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 umožňují 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 následné iterace. Výchozí hodnota je pět sekund.
  • Period: Doba výkonu IHealthCheckPublisher. Výchozí hodnota je 30 sekund.
  • Predicate: Pokud Predicate je null (výchozí), služba publikování zdravotních kontrol spustí všechny registrované zdravotní kontroly. 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. Použijte InfiniteTimeSpan ke spuštění bez časového limitu. Výchozí hodnota je 30 sekund.

V ukázkové aplikaci je implementace ReadinessPublisherIHealthCheckPublisher. Stav kontroly se protokoluje pro každou kontrolu na úrovni protokolování:

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 ukázkové aplikace LivenessProbeStartupStartupHostedService má kontrola připravenosti zpoždění spuštění dvě sekundy a provádí kontrolu každých 30 sekund. K aktivaci IHealthCheckPublisher implementace ukázka registruje ReadinessPublisher jako singletonní službu v kontejneru injekce 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>();

Note

AspNetCore.Diagnostics.HealthChecks zahrnuje vydavatele pro několik systémů, včetně Application Insights.

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

Omezení kontrol stavu pomocí MapWhen

Pomocí MapWhen směrujte podmíněně potrubí požadavků pro koncové body kontroly stavu.

V následujícím příkladu MapWhen se kanál požadavků větví tak, aby se aktivoval middleware kontrol stavu, pokud je pro koncový bod api/HealthCheck přijata žádost 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 ASP.NET Core middleware.

ASP.NET Core nabízí middleware pro kontroly stavu a knihovny pro hlášení stavu komponent infrastruktury aplikace.

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 vyrovnavače 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 stanoví, jaké typy testů 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 zaregistruje služby kontrol stavu a vyvolá middleware pro kontroly stavu, aby na adrese URL koncového bodu vracel odpověď o stavu. 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 zdravou, 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 HealthStatus, HealthStatus.Healthy, HealthStatus.Degraded, nebo HealthStatus.Unhealthy.

Zaregistrujte služby zdravotní kontroly v AddHealthChecks v Program.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();

DockerHEALTHCHECK

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í obrázky založené na Alpine Linuxu, mohou použít wget namísto curl.

Vytvořit kontroly stavu

Kontroly zdraví se vytvářejí implementací rozhraní IHealthCheck. 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é klíče a hodnoty.

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 s nastaveným HealthReportEntry.Status na FailureStatus. Tento stav je definován AddCheck (viz část Registrace služeb kontroly stavu) a obsahuje vnitřní výjimku, která způsobila selhání kontroly. Description je 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");

AddCheck Přetížení zobrazené v následujícím příkladu nastaví stav selhání (HealthStatus), který má být hlášen, když kontrola stavu indikuje 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 prosazován aplikací, když dojde k selhání kontroly stavu, pokud implementace kontroly stavu respektuje toto 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í funkce AddTypeActivatedCheck pro předání argumentů implementaci kontroly stavu V následujícím příkladu přijímá kontrola stavu aktivovaná pomocí typu celé číslo a řetězec ve svém 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 s celým číslem a řetězcem předanými jako argumenty.

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

Použití kontrol stavu při směrování

V Program.cs zavolejte v MapHealthChecks na sestavení koncového bodu pomocí adresy URL koncového bodu nebo relativní cesty:

app.MapHealthChecks("/healthz");

Vyžadovat hostitele (server)

Použijte RequireHost k zadání jednoho nebo více povolených hostitelů pro koncový bod kontroly stavu. Hostitelé by měli používat kódování Unicode místo punycode a mohou obsahovat síťový port. Pokud není zadána žádná kolekce, je přijat jakýkoli 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");

Warning

Rozhraní API, které závisí na Host header, jako například HttpRequest.Host a RequireHost, jsou náchylná k potenciálnímu falšování ze strany klientů.

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

Zavolejte RequireAuthorization, aby se na koncovém bodu požadavku na kontrolu stavu spustil autorizační middleware. 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ů kontroly 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 zdraví:

Kontrola kondice filtrů

Middleware kontroly stavu ve výchozím nastavení spustí všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která ve volbě Predicate vrátí hodnotu typu Boolean.

Následující příklad filtruje kontroly stavu, aby se spustily pouze ty, které jsou označené sample .

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

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

Použijte ResultStatusCodes k úpravě mapování stavu zdraví 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 pro kontroly stavu přidá do odpovědi sondy hlavičky HTTP, aby se zabránilo ukládání odpovědi do mezipaměti. Pokud je výchozí hodnota false, middleware nastaví nebo přepíše hlavičky Cache-Control, Expires a Pragma, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je hodnota true, 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 zprávy o kontrolách zdraví, nastavte HealthCheckOptions.ResponseWriter vlastnost na delegáta, který vykresluje 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í odpověď JSON 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 návratových formátů JSON, 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 serializaci JSON pomocí System.Text.Json, naleznete v tématu Jak serializovat a deserializovat JSON v .NET.

Test 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.HealthChecks SELECT 1 spustí dotaz na databázi, aby potvrdil, že připojení k databázi je v pořádku.

Warning

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

Note

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

Entity Framework Core DbContext test

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

AddDbContextCheckzaregistruje kontrolu stavu pro DbContext DbContext je dodáno metodě jako TContext. Je dostupné přetížení funkce pro konfiguraci stavu selhání, značek a vlastního testovacího dotazu.

Ve výchozím nastavení:

  • DbContextHealthCheck volá metodu EF Core objektu CanConnectAsync. Můžete přizpůsobit, jaká operace se spustí při kontrole stavu, a to pomocí přetížení metod AddDbContextCheck.
  • Název kontroly stavu je název TContext typu.

Následující příklad zaregistruje DbContext a spojený DbContextHealthCheck:

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

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

Samostatné sondy připravenosti a živosti

V některých scénářích hostování se používá dvojice zdravotních kontrol k rozlišení dvou stavů aplikace.

  • Připravenost označuje, jestli aplikace běží normálně, ale není připravená přijímat žádosti.
  • Liveness označuje, jestli aplikace spadla 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 liveness procesu používáme liveness probe, žádné další kontroly nejsou prováděny. 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 zaregistrována u AddCheck v Program.cs společně s hostovanou službou. 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 živosti. Kontrola živosti filtruje všechny zdravotní kontroly vrácením false v delegátu HealthCheckOptions.Predicate. Další informace o filtrování kontrol stavu naleznete v části Filtrování kontrol stavu v tomto článku.

Před dokončením spouštěcí úlohy /healthz/ready koncový bod hlásí stav Unhealthy. 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 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 zdravotní kontroly

Pro distribuci 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 a arg2 jako parametry konstruktoru.

    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 jsou poskytována delegátu použitému k vytvoření instance kontroly stavu, když je kontrola stavu registrována pomocí rozšiřující metody. 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 zdravotní kontroly. Pokud nullse použije výchozí hodnota.
    • failureStatus: Nepovinný prvek HealthStatus, který se hlásí pro stav selhání. Pokud se použije null, použije se HealthStatus.Unhealthy.
    • 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

Po přidání IHealthCheckPublisher do kontejneru služby systém kontroly stavu pravidelně provádí kontroly stavu a volá funkci 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: Doba výkonu IHealthCheckPublisher. Výchozí hodnota je 30 sekund.
  • Predicate: Pokud Predicate je null (výchozí), služba publikování zdravotních kontrol spustí všechny registrované zdravotní kontroly. 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. Použijte InfiniteTimeSpan ke spuštění bez časového limitu. Výchozí hodnota je 30 sekund.

Následující příklad ukazuje uspořádání zdravotního vydavatele.

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 zdravotních kontrol.

Následující příklad registruje publikátora zdravotní kontroly jako singleton a konfiguruje HealthCheckPublisherOptions.

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

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

Note

AspNetCore.Diagnostics.HealthChecks zahrnuje vydavatele pro několik systémů, včetně Application Insights.

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í dependency injection není ne běžným scénářem konfigurace kontrol stavu. Každá kontrola stavu je obvykle velmi specifická pro daný test a je nakonfigurována pomocí rozšiřujících metod IHealthChecksBuilder.

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 kontejneru služby je potřeba přidat SampleHealthCheckWithDiConfig a 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 registruje middleware pro zpracování požadavků na kontroly zdraví v řetězci middlewaru.
  • MapHealthChecks zaregistruje koncový bod zdravotních kontrol. Koncový bod je identifikován a spuštěn stejně jako další koncové body v aplikaci.

Výhodou použití MapHealthChecks oproti UseHealthChecks je možnost používat middleware s podporou koncových bodů, jako je autorizace, a mít větší detailní kontrolu nad odpovídajícími zásadami. Hlavní výhodou použití UseHealthChecks oproti MapHealthChecks je přesná kontrola nad tím, kde se spouští kontroly stavu v middleware pipeline.

UseHealthChecks:

  • Ukončí pipeline, když požadavek odpovídá koncovému bodu kontroly stavu. Krátké spojení 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 kontrol stavu v kanálu.
  • Může odpovídat jakékoli cestě na portu s null nebo prázdným PathString. Umožňuje provést health check u každého požadavku 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

Dodatečné zdroje

Note

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.