Kontroly stavu v ASP.NET Core
Glenn Condron a Juergen Gutsch
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete v tomto článku ve verzi .NET 9.
ASP.NET Core nabízí middlewarové kontroly stavu a knihovny pro vytváření sestav stavu komponent infrastruktury aplikací.
Kontroly stavu jsou vystaveny aplikací jako koncové body HTTP. Koncové body kontroly stavu je možné nakonfigurovat pro různé scénáře monitorování v reálném čase:
- Sondy stavu můžou používat orchestrátory kontejnerů a nástroje pro vyrovnávání zatížení ke kontrole stavu aplikace. Orchestrátor kontejnerů může například reagovat na neúspěšnou kontrolu stavu zastavením postupného nasazení nebo restartováním kontejneru. Nástroj pro vyrovnávání zatížení může reagovat na aplikaci, která není v pořádku, směrováním provozu mimo instanci, která selhává, do instance, která je v pořádku.
- Použití paměti, disku a dalších prostředků fyzického serveru je možné monitorovat, aby byl stav v pořádku.
- Kontroly stavu můžou otestovat závislosti aplikace, jako jsou databáze a koncové body externí služby, a ověřit dostupnost a normální fungování.
Kontroly stavu se obvykle používají s externí službou monitorování nebo orchestrátorem kontejnerů ke kontrole stavu aplikace. Než do aplikace přidáte kontroly stavu, rozhodněte se, jaký monitorovací systém se má použít. Monitorovací systém určuje, jaké typy kontrol stavu se mají vytvořit a jak nakonfigurovat jejich koncové body.
Základní sonda stavu
U mnoha aplikací stačí základní konfigurace sondy stavu, která hlásí dostupnost aplikace pro zpracování požadavků (živé aktivity) ke zjištění stavu aplikace.
Základní konfigurace registruje služby kontroly stavu a volá Middleware kontroly stavu, aby reagoval na koncový bod adresy URL s odpovědí na stav. Ve výchozím nastavení nejsou žádné konkrétní kontroly stavu registrovány k testování žádné konkrétní závislosti nebo subsystému. Aplikace se považuje za v pořádku, pokud může reagovat na adresu URL koncového bodu stavu. Výchozí zapisovač odpovědí zapíše HealthStatus jako odpověď prostého textu klientovi. Je HealthStatus
HealthStatus.Healthyto , HealthStatus.Degradednebo HealthStatus.Unhealthy.
Zaregistrujte služby kontroly stavu v adresáři AddHealthChecks Program.cs
. Vytvořte koncový bod kontroly stavu voláním MapHealthChecks.
Následující příklad vytvoří koncový bod kontroly stavu na /healthz
adrese:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks();
var app = builder.Build();
app.MapHealthChecks("/healthz");
app.Run();
DockeruHEALTHCHECK
Docker nabízí integrovanou HEALTHCHECK
direktivu, která se dá použít ke kontrole stavu aplikace, která používá základní konfiguraci kontroly stavu:
HEALTHCHECK CMD curl --fail http://localhost:5000/healthz || exit
Předchozí příklad používá curl
k vytvoření požadavku HTTP na koncový bod kontroly stavu na /healthz
adrese . curl
není součástí imagí kontejneru .NET Linux, ale dá se přidat instalací požadovaného balíčku do souboru Dockerfile. Kontejnery, které používají image založené na Alpine Linuxu, můžou místo zahrnutí wget
curl
použít .
Vytváření kontrol stavu
Kontroly stavu se vytvářejí implementací IHealthCheck rozhraní. Metoda CheckHealthAsync vrátí HealthCheckResult hodnotu, která označuje stav jako Healthy
, Degraded
nebo Unhealthy
. Výsledek se zapíše jako odpověď ve formátu prostého textu s konfigurovatelným stavovým kódem. Konfigurace je popsaná v části Možnosti kontroly stavu. HealthCheckResult může také vracet volitelné páry klíč-hodnota.
Následující příklad ukazuje rozložení kontroly stavu:
public class SampleHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context, CancellationToken cancellationToken = default)
{
var isHealthy = true;
// ...
if (isHealthy)
{
return Task.FromResult(
HealthCheckResult.Healthy("A healthy result."));
}
return Task.FromResult(
new HealthCheckResult(
context.Registration.FailureStatus, "An unhealthy result."));
}
}
Logika kontroly stavu je umístěna v CheckHealthAsync metodě. Předchozí příklad nastaví fiktivní proměnnou , isHealthy
na true
. Pokud je hodnota isHealthy
nastavena na false
, HealthCheckRegistration.FailureStatus stav se vrátí.
Pokud CheckHealthAsync při kontrole vyvolá výjimku, vrátí se nová HealthReportEntry hodnota s nastavenou HealthReportEntry.Status na FailureStatushodnotu . Tento stav je definován ( AddCheck viz část Služby kontroly stavu) a obsahuje vnitřní výjimku , která způsobila selhání kontroly. Je Description nastavená na zprávu výjimky.
Registrace služeb kontroly stavu
Pokud chcete zaregistrovat službu kontroly stavu, zavolejte AddCheck do Program.cs
:
builder.Services.AddHealthChecks()
.AddCheck<SampleHealthCheck>("Sample");
Přetížení AddCheck zobrazené v následujícím příkladu nastaví stav selhání (HealthStatus) tak, aby ohlásil, když kontrola stavu hlásí selhání. Pokud je stav selhání nastavený na null
(výchozí), HealthStatus.Unhealthy je hlášeno. Toto přetížení je užitečný scénář pro autory knihoven, kde je stav selhání označený knihovnou vynucen aplikací, když dojde k selhání kontroly stavu, pokud implementace kontroly stavu dodržuje nastavení.
Značky lze použít k filtrování kontrol stavu. Značky jsou popsány v části Kontroly stavu filtru.
builder.Services.AddHealthChecks()
.AddCheck<SampleHealthCheck>(
"Sample",
failureStatus: HealthStatus.Degraded,
tags: new[] { "sample" });
AddCheck může také spustit funkci lambda. V následujícím příkladu vrátí kontrola stavu vždy výsledek, který je v pořádku:
builder.Services.AddHealthChecks()
.AddCheck("Sample", () => HealthCheckResult.Healthy("A healthy result."));
Volání AddTypeActivatedCheck pro předání argumentů implementaci kontroly stavu V následujícím příkladu přijímá kontrola stavu aktivovaná typem celé číslo a řetězec v jeho konstruktoru:
public class SampleHealthCheckWithArgs : IHealthCheck
{
private readonly int _arg1;
private readonly string _arg2;
public SampleHealthCheckWithArgs(int arg1, string arg2)
=> (_arg1, _arg2) = (arg1, arg2);
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context, CancellationToken cancellationToken = default)
{
// ...
return Task.FromResult(HealthCheckResult.Healthy("A healthy result."));
}
}
Pokud chcete zaregistrovat předchozí kontrolu stavu, zavolejte AddTypeActivatedCheck
celé číslo a řetězec předaný jako argumenty:
builder.Services.AddHealthChecks()
.AddTypeActivatedCheck<SampleHealthCheckWithArgs>(
"Sample",
failureStatus: HealthStatus.Degraded,
tags: new[] { "sample" },
args: new object[] { 1, "Arg" });
Použití směrování kontrol stavu
MapHealthChecks
Volání Program.cs
tvůrce koncových bodů pomocí adresy URL koncového bodu nebo relativní cesty:
app.MapHealthChecks("/healthz");
Vyžadovat hostitele
Volání RequireHost
pro zadání jednoho nebo více povolených hostitelů pro koncový bod kontroly stavu Hostitelé by měli mít místo punycode kódování Unicode a můžou obsahovat port. Pokud kolekci nezadáte, přijme se žádný hostitel:
app.MapHealthChecks("/healthz")
.RequireHost("www.contoso.com:5001");
Chcete-li omezit koncový bod kontroly stavu tak, aby reagoval pouze na konkrétním portu, zadejte port v volání RequireHost
. Tento přístup se obvykle používá v prostředí kontejneru k zveřejnění portu pro monitorovací služby:
app.MapHealthChecks("/healthz")
.RequireHost("*:5001");
Upozorňující
Rozhraní API, které závisí na hlavičce hostitele, například HttpRequest.Host a RequireHost, podléhají potenciálnímu falšování identity klienty.
Pokud chcete zabránit falšování identity hostitele a portu, použijte jeden z následujících přístupů:
- Použijte HttpContext.Connection (ConnectionInfo.LocalPort) místo, kde jsou porty kontrolovány.
- Používejte filtrování hostitelů.
Pokud chcete zabránit neoprávněným klientům v falšování identity portu, zavolejte RequireAuthorization:
app.MapHealthChecks("/healthz")
.RequireHost("*:5001")
.RequireAuthorization();
Další informace naleznete v tématu Porovnávání hostitelů v trasách s RequireHost.
Vyžadovat autorizaci
Volání RequireAuthorization pro spuštění autorizačního middlewaru na koncovém bodu žádosti o kontrolu stavu RequireAuthorization
Přetížení přijímá jednu nebo více zásad autorizace. Pokud zásady nejsou zadané, použije se výchozí zásada autorizace:
app.MapHealthChecks("/healthz")
.RequireAuthorization();
Povolení žádostí nepůvodního zdroje (CORS)
I když spouštění kontrol stavu ručně z prohlížeče není běžným scénářem, middleware CORS je možné povolit voláním RequireCors
koncových bodů kontrol stavu. Přetížení RequireCors
přijímá delegáta tvůrce zásad CORS (CorsPolicyBuilder
) nebo název zásady. Další informace najdete v tématu Povolení žádostí mezi zdroji (CORS) v ASP.NET Core.
Možnosti kontroly stavu
HealthCheckOptions poskytnout příležitost přizpůsobit chování kontroly stavu:
- Filtrování kontrol stavu
- Přizpůsobení stavového kódu HTTP
- Potlačení hlaviček mezipaměti
- Přizpůsobení výstupu
Filtrování kontrol stavu
Ve výchozím nastavení spustí Middleware kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která vrátí logickou hodnotu možnosti Predicate .
Následující příklad filtruje kontroly stavu tak, aby se spustily pouze ty, které jsou označené jako spuštěné sample
:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
Predicate = healthCheck => healthCheck.Tags.Contains("sample")
});
Přizpůsobení stavového kódu HTTP
Slouží ResultStatusCodes k přizpůsobení mapování stavu na stavové kódy HTTP. Následující StatusCodes přiřazení jsou výchozí hodnoty používané middlewarem. Změňte hodnoty stavového kódu tak, aby splňovaly vaše požadavky:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
}
});
Potlačení hlaviček mezipaměti
AllowCachingResponses určuje, zda middleware kontroly stavu přidává hlavičky HTTP do odpovědi sondy, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je false
hodnota (výchozí), middleware nastaví nebo přepíše Cache-Control
Expires
, a Pragma
hlavičky, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je true
hodnota, middleware nezmění hlavičky mezipaměti odpovědi:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
AllowCachingResponses = true
});
Přizpůsobení výstupu
Pokud chcete přizpůsobit výstup sestavy kontrol stavu, nastavte HealthCheckOptions.ResponseWriter vlastnost na delegáta, který zapisuje odpověď:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
ResponseWriter = WriteResponse
});
Výchozí delegát zapíše minimální odpověď prostého textu s řetězcovou hodnotou HealthReport.Status
. Následující vlastní delegát vypíše vlastní 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.
Sonda databáze
Kontrola stavu může zadat databázový dotaz, který se má spustit jako logický test, který indikuje, jestli databáze normálně reaguje.
AspNetCore.Diagnostics.HealthChecks
– knihovna kontroly stavu pro aplikace ASP.NET Core obsahuje kontrolu stavu, která se spouští v databázi SQL Serveru. AspNetCore.Diagnostics.HealthChecks
SELECT 1
spustí dotaz na databázi, aby potvrdil, že připojení k databázi je v pořádku.
Upozorňující
Při kontrole připojení k databázi s dotazem zvolte dotaz, který se rychle vrátí. Přístup k dotazům riskuje přetížení databáze a snížení výkonu. Ve většině případů není spuštění testovacího dotazu nutné. Stačí pouze úspěšné připojení k databázi. Pokud zjistíte, že je nutné spustit dotaz, zvolte jednoduchý dotaz SELECT, například SELECT 1
.
Pokud chcete použít tuto kontrolu stavu SQL Serveru, uveďte odkaz na AspNetCore.HealthChecks.SqlServer
balíček NuGet. Následující příklad zaregistruje kontrolu stavu SQL Serveru:
var conStr = builder.Configuration.GetConnectionString("DefaultConnection");
if (string.IsNullOrEmpty(conStr))
{
throw new InvalidOperationException(
"Could not find a connection string named 'DefaultConnection'.");
}
builder.Services.AddHealthChecks()
.AddSqlServer(conStr);
Poznámka:
AspNetCore.Diagnostics.HealthChecks
není udržována ani podporována společností Microsoft.
Sonda Entity Framework Core DbContext
Kontrola DbContext
potvrzuje, že aplikace může komunikovat s databází nakonfigurovanou pro aplikaci EF CoreDbContext
. Kontrola je podporovaná DbContext
v aplikacích, které:
- Použijte Entity Framework (EF) Core.
- Zahrňte odkaz na
Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
balíček NuGet.
AddDbContextCheckzaregistruje kontrolu stavu pro DbContext Metoda DbContext
je zadána jako TContext
. K dispozici je přetížení ke konfiguraci stavu selhání, značek a vlastního testovacího dotazu.
Standardně:
- EF Core
CanConnectAsync
VoláníDbContextHealthCheck
metody. Můžete přizpůsobit, jakou operaci se spustí při kontrole stavu pomocíAddDbContextCheck
přetížení metod. - Název kontroly stavu je název
TContext
typu.
Následující příklad zaregistruje a DbContext
přidružené DbContextHealthCheck
:
builder.Services.AddDbContext<SampleDbContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddHealthChecks()
.AddDbContextCheck<SampleDbContext>();
Samostatné testy připravenosti a aktivity
V některých scénářích hostování se k rozlišení dvou stavů aplikace používá pár kontrol stavu:
- Připravenost označuje, jestli aplikace běží normálně, ale není připravená přijímat žádosti.
- Liveness označuje, jestli se aplikace chybově ukončila a musí se restartovat.
Představte si následující příklad: Aplikace musí stáhnout velký konfigurační soubor, než bude připraven zpracovávat požadavky. Nechceme, aby se aplikace restartovala, pokud se počáteční stahování nezdaří, protože aplikace může několikrát zkusit stáhnout soubor znovu. K popisu aktivity procesu používáme sondu živé aktivity, nespustíme žádné další kontroly. Chceme také zabránit tomu, aby se žádosti odesílaly do aplikace před úspěšným stažením konfiguračního souboru. Sondu připravenosti použijeme k označení stavu "nepřipraveno", dokud stahování nebude úspěšné a aplikace bude připravená přijímat žádosti.
Následující úloha na pozadí simuluje proces spuštění, který trvá přibližně 15 sekund. Po dokončení nastaví úloha StartupHealthCheck.StartupCompleted
vlastnost na true:
public class StartupBackgroundService : BackgroundService
{
private readonly StartupHealthCheck _healthCheck;
public StartupBackgroundService(StartupHealthCheck healthCheck)
=> _healthCheck = healthCheck;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// Simulate the effect of a long-running task.
await Task.Delay(TimeSpan.FromSeconds(15), stoppingToken);
_healthCheck.StartupCompleted = true;
}
}
StartupHealthCheck
Hlásí dokončení dlouhotrvající spouštěcí úlohy a zveřejňuje StartupCompleted
vlastnost, která se nastaví službou na pozadí:
public class StartupHealthCheck : IHealthCheck
{
private volatile bool _isReady;
public bool StartupCompleted
{
get => _isReady;
set => _isReady = value;
}
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context, CancellationToken cancellationToken = default)
{
if (StartupCompleted)
{
return Task.FromResult(HealthCheckResult.Healthy("The startup task has completed."));
}
return Task.FromResult(HealthCheckResult.Unhealthy("That startup task is still running."));
}
}
Kontrola stavu je zaregistrovaná AddCheck Program.cs
společně s hostovanými službami. Vzhledem k tomu, že hostovaná služba musí nastavit vlastnost kontroly stavu, je kontrola stavu také zaregistrována v kontejneru služby jako singleton:
builder.Services.AddHostedService<StartupBackgroundService>();
builder.Services.AddSingleton<StartupHealthCheck>();
builder.Services.AddHealthChecks()
.AddCheck<StartupHealthCheck>(
"Startup",
tags: new[] { "ready" });
Pokud chcete vytvořit dva různé koncové body kontroly stavu, volejte MapHealthChecks
dvakrát:
app.MapHealthChecks("/healthz/ready", new HealthCheckOptions
{
Predicate = healthCheck => healthCheck.Tags.Contains("ready")
});
app.MapHealthChecks("/healthz/live", new HealthCheckOptions
{
Predicate = _ => false
});
Předchozí příklad vytvoří následující koncové body kontroly stavu:
/healthz/ready
pro kontrolu připravenosti. Kontrola připravenosti filtruje kontroly stavu na ty, které jsou označenéready
./healthz/live
pro kontrolu živého života. Kontrola aktivity filtruje všechny kontroly stavu vrácenímfalse
delegáta HealthCheckOptions.Predicate . Další informace o filtrování kontrol stavu najdete v tématu Filtrování kontrol stavu v tomto článku.
Před dokončením /healthz/ready
spouštěcí úlohy koncový bod hlásí Unhealthy
stav. Po dokončení spouštěcí úlohy tento koncový bod hlásí Healthy
stav. Koncový /healthz/live
bod vyloučí všechny kontroly a hlásí Healthy
stav všech volání.
Příklad Kubernetes
Použití samostatných kontrol připravenosti a aktivity je užitečné v prostředí, jako je Kubernetes. V Kubernetes může být aplikace nutná ke spouštění časově náročných spouštěcích prací před přijetím požadavků, jako je například test dostupnosti podkladové databáze. Použití samostatných kontrol umožňuje orchestrátoru rozlišit, jestli aplikace funguje, ale ještě není připravená nebo jestli se aplikaci nepodařilo spustit. Další informace o testech připravenosti a aktivity v Kubernetes najdete v dokumentaci ke konfiguraci testů živé aktivity a připravenosti v Kubernetes.
Následující příklad ukazuje konfiguraci sondy připravenosti Kubernetes:
spec:
template:
spec:
readinessProbe:
# an http probe
httpGet:
path: /healthz/ready
port: 80
# length of time to wait for a pod to initialize
# after pod startup, before applying health checking
initialDelaySeconds: 30
timeoutSeconds: 1
ports:
- containerPort: 80
Distribuce knihovny kontroly stavu
Distribuce kontroly stavu jako knihovny:
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.
Napište metodu rozšíření s parametry, které spotřebová aplikace volá ve své
Program.cs
metodě. Podívejte se na následující příklad kontroly stavu, která přijímáarg1
parametry konstruktoru aarg2
jako parametry:public SampleHealthCheckWithArgs(int arg1, string arg2) => (_arg1, _arg2) = (arg1, arg2);
Předchozí podpis označuje, že kontrola stavu vyžaduje vlastní data ke zpracování logiky sondy kontroly stavu. Data se poskytují delegátu použitému k vytvoření instance kontroly stavu při registraci kontroly stavu v metodě rozšíření. V následujícím příkladu volající určuje:
arg1
: Celočíselná datová hodnota pro kontrolu stavu.arg2
: Řetězcový argument pro kontrolu stavu.name
: Volitelný název kontroly stavu. Pokudnull
se použije výchozí hodnota.failureStatus
: Nepovinný údaj HealthStatus, který je hlášen pro stav selhání. Pokudnull
se použije , HealthStatus.Unhealthy použije se.tags
: VolitelnáIEnumerable<string>
kolekce značek.
public static class SampleHealthCheckBuilderExtensions { private const string DefaultName = "Sample"; public static IHealthChecksBuilder AddSampleHealthCheck( this IHealthChecksBuilder healthChecksBuilder, int arg1, string arg2, string? name = null, HealthStatus? failureStatus = null, IEnumerable<string>? tags = default) { return healthChecksBuilder.Add( new HealthCheckRegistration( name ?? DefaultName, _ => new SampleHealthCheckWithArgs(arg1, arg2), failureStatus, tags)); } }
Kontrola stavu – Vydavatel
IHealthCheckPublisher Po přidání do kontejneru služby systém kontroly stavu pravidelně provádí kontroly stavu a volání PublishAsync s výsledkem. Tento proces je užitečný ve scénáři systému monitorování stavu založeného na nabízených oznámeních, který očekává, že každý proces bude pravidelně volat monitorovací systém, aby zjistil stav.
HealthCheckPublisherOptions umožňuje nastavit:
- Delay: Počáteční prodleva použitá po spuštění aplikace před spuštěním IHealthCheckPublisher instancí. Zpoždění se použije jednou při spuštění a nevztahuje se na pozdější iterace. Výchozí hodnota je pět sekund.
- Period: Období IHealthCheckPublisher provádění. Výchozí hodnota je 30 sekund.
- Predicate: Pokud Predicate je
null
(výchozí), spustí služba vydavatele kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která filtruje sadu kontrol. Predikát se vyhodnocuje každé období. - Timeout: Časový limit pro provádění kontrol stavu pro všechny IHealthCheckPublisher instance. Slouží InfiniteTimeSpan ke spuštění bez časového limitu. Výchozí hodnota je 30 sekund.
Následující příklad ukazuje rozložení vydavatele stavu:
public class SampleHealthCheckPublisher : IHealthCheckPublisher
{
public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
{
if (report.Status == HealthStatus.Healthy)
{
// ...
}
else
{
// ...
}
return Task.CompletedTask;
}
}
Třída HealthCheckPublisherOptions poskytuje vlastnosti pro konfiguraci chování vydavatele kontroly stavu.
Následující příklad zaregistruje vydavatele kontroly stavu jako singleton a nakonfiguruje HealthCheckPublisherOptions:
builder.Services.Configure<HealthCheckPublisherOptions>(options =>
{
options.Delay = TimeSpan.FromSeconds(2);
options.Predicate = healthCheck => healthCheck.Tags.Contains("sample");
});
builder.Services.AddSingleton<IHealthCheckPublisher, SampleHealthCheckPublisher>();
AspNetCore.Diagnostics.HealthChecks
:
- Zahrnuje vydavatele pro několik systémů, včetně Application Insights.
- Společnost Microsoft není udržována ani podporována.
Jednotlivé kontroly stavu
Delay
a Period
lze je nastavit jednotlivě HealthCheckRegistration . To je užitečné, když chcete spustit některé kontroly stavu s jinou rychlostí, než je doba nastavená v HealthCheckPublisherOptions.
Následující kód nastaví Delay
a Period
pro SampleHealthCheck1
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks()
.Add(new HealthCheckRegistration(
name: "SampleHealthCheck1",
instance: new SampleHealthCheck(),
failureStatus: null,
tags: null,
timeout: default)
{
Delay = TimeSpan.FromSeconds(40),
Period = TimeSpan.FromSeconds(30)
});
var app = builder.Build();
app.MapHealthChecks("/healthz");
app.Run();
Injektáž závislostí a kontroly stavu
Injektáž závislostí je možné použít ke spotřebování instance konkrétní Type
instance uvnitř třídy kontroly stavu. Injektáž závislostí může být užitečná pro vložení možností nebo globální konfigurace do kontroly stavu. Použití injektáže závislostí není běžným scénářem konfigurace kontrol stavu. Každá kontrola stavu je obvykle zcela specifická pro skutečný test a je nakonfigurovaná pomocí IHealthChecksBuilder
rozšiřujících metod.
Následující příklad ukazuje ukázkovou kontrolu stavu, která načte objekt konfigurace prostřednictvím injektáže závislostí:
public class SampleHealthCheckWithDI : IHealthCheck
{
private readonly SampleHealthCheckWithDiConfig _config;
public SampleHealthCheckWithDI(SampleHealthCheckWithDiConfig config)
=> _config = config;
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context, CancellationToken cancellationToken = default)
{
var isHealthy = true;
// use _config ...
if (isHealthy)
{
return Task.FromResult(
HealthCheckResult.Healthy("A healthy result."));
}
return Task.FromResult(
new HealthCheckResult(
context.Registration.FailureStatus, "An unhealthy result."));
}
}
Do SampleHealthCheckWithDiConfig
kontejneru služby je potřeba přidat kontrolu stavu:
builder.Services.AddSingleton<SampleHealthCheckWithDiConfig>(new SampleHealthCheckWithDiConfig
{
BaseUriToCheck = new Uri("https://sample.contoso.com/api/")
});
builder.Services.AddHealthChecks()
.AddCheck<SampleHealthCheckWithDI>(
"With Dependency Injection",
tags: new[] { "inject" });
UseHealthChecks vs. MapHealthChecks
Existují dva způsoby zpřístupnění kontrol stavu volajícím:
- UseHealthChecks zaregistruje middleware pro zpracování žádostí o kontroly stavu v kanálu middlewaru.
- MapHealthChecks zaregistruje koncový bod kontroly stavu. Koncový bod se porovná a spustí spolu s dalšími koncovými body v aplikaci.
Výhodou použití MapHealthChecks
oproti UseHealthChecks
tomu je možnost používat middleware s podporou koncových bodů, jako je autorizace, a mít větší jemně odstupňovanou kontrolu nad odpovídajícími zásadami. Hlavní výhodou použití UseHealthChecks
je MapHealthChecks
řízení přesně toho, kde se kontroly stavu spouští v kanálu middlewaru.
- Ukončí kanál, když požadavek odpovídá koncovému bodu kontroly stavu. Zkratování je často žádoucí, protože zabraňuje zbytečné práci, jako je protokolování a další middleware.
- Primárně se používá ke konfiguraci middlewaru kontroly stavu v kanálu.
- Může odpovídat jakékoli cestě na portu s nebo prázdným
null
PathString
. Umožňuje provést kontrolu stavu u všech požadavků provedených na zadaném portu. - Zdrojový kód
MapHealthChecks umožňuje:
- Ukončení kanálu, když požadavek odpovídá koncovému bodu kontroly stavu voláním ShortCircuit. Například
app.MapHealthChecks("/healthz").ShortCircuit();
. Další informace najdete v tématu Middleware s krátkým okruhem po směrování. - Mapování konkrétních tras nebo koncových bodů pro kontroly stavu
- Přizpůsobení adresy URL nebo cesty, kde je koncový bod kontroly stavu přístupný.
- Mapování několika koncových bodů kontroly stavu s různými trasami nebo konfiguracemi Podpora více koncových bodů:
- Umožňuje samostatné koncové body pro různé typy kontrol stavu nebo součástí.
- Používá se k rozlišení různých aspektů stavu aplikace nebo použití konkrétních konfigurací na podmnožinu kontrol stavu.
- Zdrojový kód
Další materiály
Poznámka:
Tento článek byl částečně vytvořen pomocí umělé inteligence. Před zveřejněním autor obsah zkontroloval a podle potřeby upravil. Viz Naše zásady pro používání obsahu generovaného AI v Microsoft Learn.
ASP.NET Core nabízí middlewarové kontroly stavu a knihovny pro vytváření sestav stavu komponent infrastruktury aplikací.
Kontroly stavu jsou vystaveny aplikací jako koncové body HTTP. Koncové body kontroly stavu je možné nakonfigurovat pro různé scénáře monitorování v reálném čase:
- Sondy stavu můžou používat orchestrátory kontejnerů a nástroje pro vyrovnávání zatížení ke kontrole stavu aplikace. Orchestrátor kontejnerů může například reagovat na neúspěšnou kontrolu stavu zastavením postupného nasazení nebo restartováním kontejneru. Nástroj pro vyrovnávání zatížení může reagovat na aplikaci, která není v pořádku, směrováním provozu mimo instanci, která selhává, do instance, která je v pořádku.
- Použití paměti, disku a dalších prostředků fyzického serveru je možné monitorovat, aby byl stav v pořádku.
- Kontroly stavu můžou otestovat závislosti aplikace, jako jsou databáze a koncové body externí služby, a ověřit dostupnost a normální fungování.
Zobrazení nebo stažení ukázkového kódu (postup stažení)
Ukázková aplikace obsahuje příklady scénářů popsaných v tomto článku. Pokud chcete spustit ukázkovou aplikaci pro daný scénář, použijte příkaz dotnet run ze složky projektu v příkazovém prostředí. Podrobnosti o používání ukázkové aplikace najdete v souboru ukázkové aplikace README.md
a popisech scénářů v tomto článku.
Požadavky
Kontroly stavu se obvykle používají s externí službou monitorování nebo orchestrátorem kontejnerů ke kontrole stavu aplikace. Než do aplikace přidáte kontroly stavu, rozhodněte se, jaký monitorovací systém se má použít. Monitorovací systém určuje, jaké typy kontrol stavu se mají vytvořit a jak nakonfigurovat jejich koncové body.
Na Microsoft.AspNetCore.Diagnostics.HealthChecks
balíček se implicitně odkazuje pro aplikace ASP.NET Core. Pokud chcete spouštět kontroly stavu pomocí Entity Framework Core, přidejte odkaz na Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
balíček.
Ukázková aplikace poskytuje spouštěcí kód, který demonstruje kontroly stavu pro několik scénářů. Scénář sondy databáze kontroluje stav připojení k databázi pomocí AspNetCore.Diagnostics.HealthChecks
. Scénář sondy DbContext kontroluje databázi pomocí .EF CoreDbContext
Pokud chcete prozkoumat databázové scénáře, ukázková aplikace:
- Vytvoří databázi a poskytne její připojovací řetězec v
appsettings.json
souboru. - Obsahuje následující odkazy na balíčky v souboru projektu:
Poznámka:
AspNetCore.Diagnostics.HealthChecks
není udržována ani podporována společností Microsoft.
Další scénář kontroly stavu ukazuje, jak filtrovat kontroly stavu na port pro správu. Ukázková aplikace vyžaduje, Properties/launchSettings.json
abyste vytvořili soubor, který obsahuje adresu URL pro správu a port pro správu. Další informace najdete v části Filtrovat podle portu .
Základní sonda stavu
U mnoha aplikací stačí základní konfigurace sondy stavu, která hlásí dostupnost aplikace pro zpracování požadavků (živé aktivity) ke zjištění stavu aplikace.
Základní konfigurace registruje služby kontroly stavu a volá Middleware kontroly stavu, aby reagoval na koncový bod adresy URL s odpovědí na stav. Ve výchozím nastavení nejsou žádné konkrétní kontroly stavu registrovány k testování žádné konkrétní závislosti nebo subsystému. Aplikace se považuje za v pořádku, pokud může reagovat na adresu URL koncového bodu stavu. Výchozí zapisovač odpovědí zapíše stav (HealthStatus) jako odpověď ve formátu prostého textu zpět klientovi, který označuje HealthStatus.Healthyhodnotu , HealthStatus.Degradednebo HealthStatus.Unhealthy stav.
Zaregistrujte služby kontroly stavu v adresáři AddHealthChecks Startup.ConfigureServices
. Vytvořte koncový bod kontroly stavu voláním MapHealthChecks
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
Vytváření kontrol stavu
Kontroly stavu se vytvářejí implementací IHealthCheck rozhraní. Metoda CheckHealthAsync vrátí HealthCheckResult hodnotu, která označuje stav jako Healthy
, Degraded
nebo Unhealthy
. Výsledek se zapíše jako odpověď prostého textu s konfigurovatelným stavovým kódem (konfigurace je popsaná v části Možnosti kontroly stavu). HealthCheckResult může také vracet volitelné páry klíč-hodnota.
Následující ExampleHealthCheck
třída ukazuje rozložení kontroly stavu. Logika kontroly stavu je umístěna CheckHealthAsync
v metodě. Následující příklad nastaví fiktivní proměnnou , healthCheckResultHealthy
na true
. Pokud je hodnota healthCheckResultHealthy
nastavena na false
, HealthCheckRegistration.FailureStatus stav se vrátí.
public class ExampleHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default(CancellationToken))
{
var healthCheckResultHealthy = true;
if (healthCheckResultHealthy)
{
return Task.FromResult(
HealthCheckResult.Healthy("A healthy result."));
}
return Task.FromResult(
new HealthCheckResult(context.Registration.FailureStatus,
"An unhealthy result."));
}
}
Pokud CheckHealthAsync při kontrole vyvolá výjimku, vrátí se nová HealthReportEntry položka s HealthReportEntry.Status nastavenou na hodnotu FailureStatusdefinovanou AddCheck (viz část Služby kontroly stavu registru) a obsahuje vnitřní výjimku , která původně způsobila chybu kontroly. Je Description nastavená na zprávu výjimky.
Registrace služeb kontroly stavu
Typ ExampleHealthCheck
se přidá ke službám kontroly stavu s následujícími položkami AddCheck Startup.ConfigureServices
:
services.AddHealthChecks()
.AddCheck<ExampleHealthCheck>("example_health_check");
Přetížení AddCheck zobrazené v následujícím příkladu nastaví stav selhání (HealthStatus) tak, aby ohlásil, když kontrola stavu hlásí selhání. Pokud je stav selhání nastavený na null
(výchozí), HealthStatus.Unhealthy je hlášeno. Toto přetížení je užitečný scénář pro autory knihoven, kde je stav selhání označený knihovnou vynucen aplikací, když dojde k selhání kontroly stavu, pokud implementace kontroly stavu dodržuje nastavení.
Značky lze použít k filtrování kontrol stavu (popsáno dále v části Kontroly stavu filtru).
services.AddHealthChecks()
.AddCheck<ExampleHealthCheck>(
"example_health_check",
failureStatus: HealthStatus.Degraded,
tags: new[] { "example" });
AddCheck může také spustit funkci lambda. V následujícím příkladu je název kontroly stavu zadán jako Example
a kontrola vždy vrátí stav v pořádku:
services.AddHealthChecks()
.AddCheck("Example", () =>
HealthCheckResult.Healthy("Example is OK!"), tags: new[] { "example" });
Volání AddTypeActivatedCheck pro předání argumentů implementaci kontroly stavu V následujícím příkladu TestHealthCheckWithArgs
přijímá celé číslo a řetězec pro použití, pokud CheckHealthAsync je volán:
private class TestHealthCheckWithArgs : IHealthCheck
{
public TestHealthCheckWithArgs(int i, string s)
{
I = i;
S = s;
}
public int I { get; set; }
public string S { get; set; }
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context,
CancellationToken cancellationToken = default)
{
...
}
}
TestHealthCheckWithArgs
je registrován voláním AddTypeActivatedCheck
celého čísla a řetězce předaného implementaci:
services.AddHealthChecks()
.AddTypeActivatedCheck<TestHealthCheckWithArgs>(
"test",
failureStatus: HealthStatus.Degraded,
tags: new[] { "example" },
args: new object[] { 5, "string" });
Použití směrování kontrol stavu
MapHealthChecks
Volání Startup.Configure
tvůrce koncových bodů pomocí adresy URL koncového bodu nebo relativní cesty:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
});
Vyžadovat hostitele
Volání RequireHost
pro zadání jednoho nebo více povolených hostitelů pro koncový bod kontroly stavu Hostitelé by měli mít místo punycode kódování Unicode a můžou obsahovat port. Pokud kolekci nezadáte, přijme se žádný hostitel.
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health").RequireHost("www.contoso.com:5001");
});
Další informace najdete v části Filtrovat podle portu .
Vyžadovat autorizaci
Volání RequireAuthorization
pro spuštění autorizačního middlewaru na koncovém bodu žádosti o kontrolu stavu RequireAuthorization
Přetížení přijímá jednu nebo více zásad autorizace. Pokud zásady nejsou zadané, použijí se výchozí zásady autorizace.
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health").RequireAuthorization();
});
Povolení žádostí nepůvodního zdroje (CORS)
I když spouštění kontrol stavu ručně z prohlížeče není běžným scénářem použití, middleware CORS je možné povolit voláním RequireCors
koncových bodů kontrol stavu. RequireCors
Přetížení přijímá delegátaCorsPolicyBuilder
() nebo název zásady CORS. Pokud zásady nejsou zadané, použije se výchozí zásada CORS. Další informace najdete v tématu Povolení žádostí mezi zdroji (CORS) v ASP.NET Core.
Možnosti kontroly stavu
HealthCheckOptions poskytnout příležitost přizpůsobit chování kontroly stavu:
- Filtrování kontrol stavu
- Přizpůsobení stavového kódu HTTP
- Potlačení hlaviček mezipaměti
- Přizpůsobení výstupu
Filtrování kontrol stavu
Ve výchozím nastavení spustí Middleware kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která vrátí logickou hodnotu možnosti Predicate . V následujícím příkladu Bar
se kontrola stavu vyfiltruje podle značky (bar_tag
) v podmíněném příkazu funkce, kde true
se vrátí pouze v případě, že se vlastnost kontroly Tags stavu shoduje foo_tag
nebo baz_tag
:
V Startup.ConfigureServices
:
services.AddHealthChecks()
.AddCheck("Foo", () =>
HealthCheckResult.Healthy("Foo is OK!"), tags: new[] { "foo_tag" })
.AddCheck("Bar", () =>
HealthCheckResult.Unhealthy("Bar is unhealthy!"), tags: new[] { "bar_tag" })
.AddCheck("Baz", () =>
HealthCheckResult.Healthy("Baz is OK!"), tags: new[] { "baz_tag" });
Vyfiltruje Startup.Configure
Predicate
kontrolu stavu panelu. Pouze Foo a Baz provést:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
Predicate = (check) => check.Tags.Contains("foo_tag") ||
check.Tags.Contains("baz_tag")
});
});
Přizpůsobení stavového kódu HTTP
Slouží ResultStatusCodes k přizpůsobení mapování stavu na stavové kódy HTTP. Následující StatusCodes přiřazení jsou výchozí hodnoty používané middlewarem. Změňte hodnoty stavového kódu tak, aby splňovaly vaše požadavky.
V Startup.Configure
:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
}
});
});
Potlačení hlaviček mezipaměti
AllowCachingResponses určuje, zda middleware kontroly stavu přidává hlavičky HTTP do odpovědi sondy, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je false
hodnota (výchozí), middleware nastaví nebo přepíše Cache-Control
Expires
, a Pragma
hlavičky, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je true
hodnota, middleware neupraví hlavičky mezipaměti odpovědi.
V Startup.Configure
:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
AllowCachingResponses = true
});
});
Přizpůsobení výstupu
Nastavte Startup.Configure
možnost HealthCheckOptions.ResponseWriter delegáta pro zápis odpovědi:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
ResponseWriter = WriteResponse
});
});
Výchozí delegát zapíše minimální odpověď prostého textu s řetězcovou hodnotou HealthReport.Status
. Následující vlastní delegáti vypíše vlastní odpověď 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 SYSTEM_TEXT_JSON
, aby bylo možné povolit Newtonsoft.Json
verzi WriteResponse
. CustomWriterStartup.cs
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.
Sonda databáze
Kontrola stavu může zadat databázový dotaz, který se má spustit jako logický test, který indikuje, jestli databáze normálně reaguje.
Ukázková aplikace používá AspNetCore.Diagnostics.HealthChecks
knihovnu kontroly stavu pro aplikace ASP.NET Core ke spuštění kontroly stavu 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.
Upozorňující
Při kontrole připojení k databázi s dotazem zvolte dotaz, který se rychle vrátí. Přístup k dotazům riskuje přetížení databáze a snížení výkonu. Ve většině případů není spuštění testovacího dotazu nutné. Stačí pouze úspěšné připojení k databázi. Pokud zjistíte, že je nutné spustit dotaz, zvolte jednoduchý dotaz SELECT, například SELECT 1
.
Zahrnout odkaz na AspNetCore.HealthChecks.SqlServer
balíček .
Do souboru ukázkové aplikace zadejte platný připojovací řetězec appsettings.json
databáze. Aplikace používá databázi SQL Serveru s názvem HealthCheckSample
:
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=HealthCheckSample;Trusted_Connection=True;MultipleActiveResultSets=true;ConnectRetryCount=0"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
},
"Console": {
"IncludeScopes": "true"
}
},
"AllowedHosts": "*"
}
Zaregistrujte služby kontroly stavu v adresáři AddHealthChecks Startup.ConfigureServices
. Ukázková aplikace volá metodu AddSqlServer
s připojovací řetězec databáze (DbHealthStartup.cs
):
services.AddHealthChecks()
.AddSqlServer(Configuration["ConnectionStrings:DefaultConnection"]);
Koncový bod kontroly stavu se vytvoří voláním MapHealthChecks
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
Poznámka:
AspNetCore.Diagnostics.HealthChecks
není udržována ani podporována společností Microsoft.
Sonda Entity Framework Core DbContext
Kontrola DbContext
potvrzuje, že aplikace může komunikovat s databází nakonfigurovanou pro aplikaci EF CoreDbContext
. Kontrola je podporovaná DbContext
v aplikacích, které:
- Použijte Entity Framework (EF) Core.
- Zahrnout odkaz na
Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
balíček .
AddDbContextCheck<TContext>
zaregistruje kontrolu stavu pro DbContext
Tato DbContext
metoda je zadána TContext
jako metoda. K dispozici je přetížení ke konfiguraci stavu selhání, značek a vlastního testovacího dotazu.
Standardně:
- EF Core
CanConnectAsync
VoláníDbContextHealthCheck
metody. Můžete přizpůsobit, jakou operaci se spustí při kontrole stavu pomocíAddDbContextCheck
přetížení metod. - Název kontroly stavu je název
TContext
typu.
V ukázkové aplikaci AppDbContext
se poskytuje AddDbContextCheck
a zaregistruje jako služba v Startup.ConfigureServices
:DbContextHealthStartup.cs
services.AddHealthChecks()
.AddDbContextCheck<AppDbContext>();
services.AddDbContext<AppDbContext>(options =>
{
options.UseSqlServer(
Configuration["ConnectionStrings:DefaultConnection"]);
});
Koncový bod kontroly stavu se vytvoří voláním MapHealthChecks
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í řetězec v instanci SQL Serveru neexistuje. Pokud databáze existuje, odstraňte ji.
V příkazovém prostředí spusťte následující příkaz ze složky projektu:
dotnet run --scenario dbcontext
Po spuštění aplikace zkontrolujte stav provedením požadavku na /health
koncový bod v prohlížeči. Databáze a AppDbContext
neexistuje, takže aplikace poskytuje následující odpověď:
Unhealthy
Aktivujte ukázkovou aplikaci a vytvořte databázi. Vytvořte žádost na /createdatabase
. Aplikace reaguje:
Creating the database...
Done!
Navigate to /health to see the health status.
Vytvořte požadavek na /health
koncový bod. Databáze a kontext existují, takže aplikace reaguje:
Healthy
Aktivujte ukázkovou aplikaci, aby se databáze odstranila. Vytvořte žádost na /deletedatabase
. Aplikace reaguje:
Deleting the database...
Done!
Navigate to /health to see the health status.
Vytvořte požadavek na /health
koncový bod. Aplikace poskytuje odpověď, která není v pořádku:
Unhealthy
Samostatné testy připravenosti a aktivity
V některých scénářích hostování se k rozlišení dvou stavů aplikace používá pár kontrol stavu:
- Připravenost označuje, jestli aplikace běží normálně, ale není připravená přijímat žádosti.
- Liveness označuje, jestli se aplikace chybově ukončila a musí se restartovat.
Představte si následující příklad: Aplikace musí stáhnout velký konfigurační soubor, než bude připraven zpracovávat požadavky. Nechceme, aby se aplikace restartovala, pokud se počáteční stahování nezdaří, protože aplikace může několikrát zkusit stáhnout soubor znovu. K popisu aktivity procesu používáme sondu živé aktivity, nespustíme žádné další kontroly. Chceme také zabránit tomu, aby se žádosti odesílaly do aplikace před úspěšným stažením konfiguračního souboru. Sondu připravenosti použijeme k označení stavu "nepřipraveno", dokud stahování nebude úspěšné a aplikace bude připravená přijímat žádosti.
Ukázková aplikace obsahuje kontrolu stavu, která hlásí dokončení dlouhotrvající spouštěcí úlohy v hostované službě. Zpřístupňuje StartupHostedServiceHealthCheck
vlastnost, StartupTaskCompleted
kterou hostovaná služba může nastavit na true
po dokončení dlouhotrvající úlohy (StartupHostedServiceHealthCheck.cs
):
public class StartupHostedServiceHealthCheck : IHealthCheck
{
private volatile bool _startupTaskCompleted = false;
public string Name => "slow_dependency_check";
public bool StartupTaskCompleted
{
get => _startupTaskCompleted;
set => _startupTaskCompleted = value;
}
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default(CancellationToken))
{
if (StartupTaskCompleted)
{
return Task.FromResult(
HealthCheckResult.Healthy("The startup task is finished."));
}
return Task.FromResult(
HealthCheckResult.Unhealthy("The startup task is still running."));
}
}
Dlouhotrvající úloha na pozadí je spuštěna hostované službou (Services/StartupHostedService
). Na závěr úkolu StartupHostedServiceHealthCheck.StartupTaskCompleted
je nastaveno:true
public class StartupHostedService : IHostedService, IDisposable
{
private readonly int _delaySeconds = 15;
private readonly ILogger _logger;
private readonly StartupHostedServiceHealthCheck _startupHostedServiceHealthCheck;
public StartupHostedService(ILogger<StartupHostedService> logger,
StartupHostedServiceHealthCheck startupHostedServiceHealthCheck)
{
_logger = logger;
_startupHostedServiceHealthCheck = startupHostedServiceHealthCheck;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Startup Background Service is starting.");
// Simulate the effect of a long-running startup task.
Task.Run(async () =>
{
await Task.Delay(_delaySeconds * 1000);
_startupHostedServiceHealthCheck.StartupTaskCompleted = true;
_logger.LogInformation("Startup Background Service has started.");
});
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Startup Background Service is stopping.");
return Task.CompletedTask;
}
public void Dispose()
{
}
}
Kontrola stavu je zaregistrovaná AddCheck Startup.ConfigureServices
společně s hostovanými službami. Vzhledem k tomu, že hostovaná služba musí nastavit vlastnost kontroly stavu, je kontrola stavu také zaregistrovaná v kontejneru služby (LivenessProbeStartup.cs
):
services.AddHostedService<StartupHostedService>();
services.AddSingleton<StartupHostedServiceHealthCheck>();
services.AddHealthChecks()
.AddCheck<StartupHostedServiceHealthCheck>(
"hosted_service_startup",
failureStatus: HealthStatus.Degraded,
tags: new[] { "ready" });
services.Configure<HealthCheckPublisherOptions>(options =>
{
options.Delay = TimeSpan.FromSeconds(2);
options.Predicate = (check) => check.Tags.Contains("ready");
});
services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();
Koncový bod kontroly stavu se vytvoří voláním MapHealthChecks
Startup.Configure
. V ukázkové aplikaci se koncové body kontroly stavu vytvoří na adrese:
/health/ready
pro kontrolu připravenosti. Kontrola připravenosti filtruje kontroly stavu na kontrolu stavu pomocí značkyready
./health/live
pro kontrolu živého života. Kontrola aktivity filtrujeStartupHostedServiceHealthCheck
vrácenímfalse
se změnami (další informace najdete vHealthCheckOptions.Predicate
tématu Kontroly stavu filtru).
V následujícím příkladu kódu:
- Kontrola připravenosti používá všechny registrované kontroly se značkou Připraveno.
- Vyloučí
Predicate
všechny kontroly a vrátí hodnotu 200-OK.
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions()
{
Predicate = (check) => check.Tags.Contains("ready"),
});
endpoints.MapHealthChecks("/health/live", new HealthCheckOptions()
{
Predicate = (_) => false
});
}
Pokud chcete spustit scénář konfigurace připravenosti a aktivity pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:
dotnet run --scenario liveness
V prohlížeči navštivte /health/ready
několikrát, dokud nepřejde 15 sekund. Kontrola stavu hlásí Unhealthy
prvních 15 sekund. Po 15 sekundách koncový bod hlásí Healthy
dokončení dlouhotrvající úlohy hostované služby.
Tento příklad také vytvoří vydavatele kontroly stavu (IHealthCheckPublisher implementaci), který spustí první kontrolu připravenosti se dvěma sekundami zpoždění. Další informace najdete v části Vydavatele kontroly stavu.
Příklad Kubernetes
Použití samostatných kontrol připravenosti a aktivity je užitečné v prostředí, jako je Kubernetes. V Kubernetes může být aplikace nutná ke spouštění časově náročných spouštěcích prací před přijetím požadavků, jako je například test dostupnosti podkladové databáze. Použití samostatných kontrol umožňuje orchestrátoru rozlišit, jestli aplikace funguje, ale ještě není připravená nebo jestli se aplikaci nepodařilo spustit. Další informace o testech připravenosti a aktivity v Kubernetes najdete v dokumentaci ke konfiguraci testů živé aktivity a připravenosti v Kubernetes.
Následující příklad ukazuje konfiguraci sondy připravenosti Kubernetes:
spec:
template:
spec:
readinessProbe:
# an http probe
httpGet:
path: /health/ready
port: 80
# length of time to wait for a pod to initialize
# after pod startup, before applying health checking
initialDelaySeconds: 30
timeoutSeconds: 1
ports:
- containerPort: 80
Sonda založená na metrikách s vlastním zapisovačem odpovědí
Ukázková aplikace ukazuje kontrolu stavu paměti pomocí vlastního zapisovače odpovědí.
MemoryHealthCheck
hlásí snížený stav, pokud aplikace používá více než danou prahovou hodnotu paměti (1 GB v ukázkové aplikaci). Obsahuje HealthCheckResult informace o uvolňování paměti (GC) pro aplikaci (MemoryHealthCheck.cs
):
public class MemoryHealthCheck : IHealthCheck
{
private readonly IOptionsMonitor<MemoryCheckOptions> _options;
public MemoryHealthCheck(IOptionsMonitor<MemoryCheckOptions> options)
{
_options = options;
}
public string Name => "memory_check";
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default(CancellationToken))
{
var options = _options.Get(context.Registration.Name);
// Include GC information in the reported diagnostics.
var allocated = GC.GetTotalMemory(forceFullCollection: false);
var data = new Dictionary<string, object>()
{
{ "AllocatedBytes", allocated },
{ "Gen0Collections", GC.CollectionCount(0) },
{ "Gen1Collections", GC.CollectionCount(1) },
{ "Gen2Collections", GC.CollectionCount(2) },
};
var status = (allocated < options.Threshold) ?
HealthStatus.Healthy : context.Registration.FailureStatus;
return Task.FromResult(new HealthCheckResult(
status,
description: "Reports degraded status if allocated bytes " +
$">= {options.Threshold} bytes.",
exception: null,
data: data));
}
}
Zaregistrujte služby kontroly stavu v adresáři AddHealthChecks 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 CustomWriterStartup.cs
ukázkové aplikaci:
services.AddHealthChecks()
.AddMemoryHealthCheck("memory");
Koncový bod kontroly stavu se vytvoří voláním MapHealthChecks
Startup.Configure
. Delegát WriteResponse
je k dispozici vlastnosti pro ResponseWriter výstup vlastní odpovědi JSON při spuštění 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
Poznámka:
AspNetCore.Diagnostics.HealthChecks
zahrnuje scénáře kontroly stavu na základě metrik, včetně diskového úložiště a kontroly maximální hodnoty liveness.
AspNetCore.Diagnostics.HealthChecks
není udržována ani podporována společností Microsoft.
Filtrovat podle portu
MapHealthChecks
Volání RequireHost
se vzorem adresy URL, který určuje port, který omezí požadavky kontroly stavu na zadaný port. Tento přístup se obvykle používá v prostředí kontejneru k vystavení portu pro monitorovací služby.
Ukázková aplikace nakonfiguruje port pomocí zprostředkovatele konfigurace proměnné prostředí. Port se nastaví v launchSettings.json
souboru a předá zprostředkovateli konfigurace prostřednictvím proměnné prostředí. Musíte také nakonfigurovat server tak, aby naslouchal požadavkům na portu pro správu.
Pokud chcete ukázkovou aplikaci použít k předvedení konfigurace portů pro správu, vytvořte launchSettings.json
soubor ve Properties
složce.
Následující Properties/launchSettings.json
soubor v ukázkové aplikaci není součástí souborů projektu ukázkové aplikace a musí být vytvořen ručně:
{
"profiles": {
"SampleApp": {
"commandName": "Project",
"commandLineArgs": "",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_URLS": "http://localhost:5000/;http://localhost:5001/",
"ASPNETCORE_MANAGEMENTPORT": "5001"
},
"applicationUrl": "http://localhost:5000/"
}
}
}
Zaregistrujte služby kontroly stavu v adresáři AddHealthChecks Startup.ConfigureServices
. Vytvořte koncový bod kontroly stavu voláním MapHealthChecks
Startup.Configure
.
V ukázkové aplikaci volání RequireHost
koncového bodu určuje Startup.Configure
port pro správu z konfigurace:
endpoints.MapHealthChecks("/health")
.RequireHost($"*:{Configuration["ManagementPort"]}");
Koncové body se vytvoří v ukázkové aplikaci v Startup.Configure
aplikaci . V následujícím příkladu kódu:
- Kontrola připravenosti používá všechny registrované kontroly se značkou Připraveno.
- Vyloučí
Predicate
všechny kontroly a vrátí hodnotu 200-OK.
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions()
{
Predicate = (check) => check.Tags.Contains("ready"),
});
endpoints.MapHealthChecks("/health/live", new HealthCheckOptions()
{
Predicate = (_) => false
});
}
Poznámka:
V ukázkové aplikaci se můžete vyhnout vytváření launchSettings.json
souboru nastavením portu pro správu explicitně v kódu. V Program.cs
místě vytvoření HostBuilder přidejte volání ListenAnyIP a zadejte koncový bod portu pro správu aplikace. V Configure
poli ManagementPortStartup.cs
, zadejte port pro správu pomocí RequireHost
:
Program.cs
:
return new HostBuilder()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseKestrel()
.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5001);
})
.UseStartup(startupType);
})
.Build();
ManagementPortStartup.cs
:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health").RequireHost("*:5001");
});
Pokud chcete spustit scénář konfigurace portu pro správu pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:
dotnet run --scenario port
Distribuce knihovny kontroly stavu
Distribuce kontroly stavu jako knihovny:
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
CheckHealthAsync
kontrol stavu :data1
adata2
používají se v metodě ke spuštění logiky kontroly stavu sondy.AccessViolationException
zpracovává se.
Když dojde k chyběAccessViolationException, vrátí HealthCheckResult se funkce umožňující FailureStatus uživatelům konfigurovat stav selhání kontrol stavu.
using System; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Diagnostics.HealthChecks; namespace SampleApp { public class ExampleHealthCheck : IHealthCheck { private readonly string _data1; private readonly int? _data2; public ExampleHealthCheck(string data1, int? data2) { _data1 = data1 ?? throw new ArgumentNullException(nameof(data1)); _data2 = data2 ?? throw new ArgumentNullException(nameof(data2)); } public async Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken) { try { return HealthCheckResult.Healthy(); } catch (AccessViolationException ex) { return new HealthCheckResult( context.Registration.FailureStatus, description: "An access violation occurred during the check.", exception: ex, data: null); } } } }
Napište metodu rozšíření s parametry, které spotřebová aplikace volá ve své
Startup.Configure
metodě. V následujícím příkladu předpokládejme následující podpis metody kontroly stavu:ExampleHealthCheck(string, string, int )
Předchozí podpis označuje, že
ExampleHealthCheck
vyžaduje další data ke zpracování logiky sondy kontroly stavu. Data se poskytují delegátu použitému k vytvoření instance kontroly stavu při registraci kontroly stavu v metodě rozšíření. V následujícím příkladu volající určuje volitelné:- název kontroly stavu (
name
). Pokudnull
se použije ,example_health_check
použije se. - datový bod řetězce pro kontrolu stavu (
data1
). - celočíselné datové body pro kontrolu stavu (
data2
). Pokudnull
se použije ,1
použije se. - stav selhání (HealthStatus). Výchozí hodnota je
null
. HealthStatus.Unhealthy Pokudnull
se zobrazí stav selhání, zobrazí se zpráva. - značky (
IEnumerable<string>
).
using System.Collections.Generic; using Microsoft.Extensions.Diagnostics.HealthChecks; public static class ExampleHealthCheckBuilderExtensions { const string DefaultName = "example_health_check"; public static IHealthChecksBuilder AddExampleHealthCheck( this IHealthChecksBuilder builder, string name = default, string data1, int data2 = 1, HealthStatus? failureStatus = default, IEnumerable<string> tags = default) { return builder.Add(new HealthCheckRegistration( name ?? DefaultName, sp => new ExampleHealthCheck(data1, data2), failureStatus, tags)); } }
- název kontroly stavu (
Kontrola stavu – Vydavatel
IHealthCheckPublisher Po přidání do kontejneru služby systém kontroly stavu pravidelně provádí kontroly stavu a volání PublishAsync
s výsledkem. To je užitečné ve scénáři systému monitorování stavu založeného na nabízených oznámeních, který očekává, že každý proces bude pravidelně volat monitorovací systém, aby zjistil stav.
Rozhraní IHealthCheckPublisher má jednu metodu:
Task PublishAsync(HealthReport report, CancellationToken cancellationToken);
HealthCheckPublisherOptions povolit nastavení:
- Delay: Počáteční prodleva použitá po spuštění aplikace před spuštěním IHealthCheckPublisher instancí. Zpoždění se použije jednou při spuštění a nevztahuje se na následné iterace. Výchozí hodnota je pět sekund.
- Period: Období IHealthCheckPublisher provádění. Výchozí hodnota je 30 sekund.
- Predicate: Pokud Predicate je
null
(výchozí), spustí služba vydavatele kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která filtruje sadu kontrol. Predikát se vyhodnocuje každé období. - Timeout: Časový limit pro provádění kontrol stavu pro všechny IHealthCheckPublisher instance. Slouží InfiniteTimeSpan ke spuštění bez časového limitu. Výchozí hodnota je 30 sekund.
V ukázkové aplikaci ReadinessPublisher
je IHealthCheckPublisher implementace. Stav kontroly stavu se protokoluje pro každou kontrolu na úrovni protokolu:
- Informace (LogInformation) pokud je Healthystav kontroly stavu .
- Chyba (LogError) pokud je stav nebo Degraded Unhealthy.
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 LivenessProbeStartup
StartupHostedService
ukázkové aplikace má kontrola připravenosti dvě sekundy zpoždění spuštění a spustí kontrolu každých 30 sekund. K aktivaci IHealthCheckPublisher implementace se ukázka zaregistruje ReadinessPublisher
jako jednoúčelová služba v kontejneru injektáže závislostí (DI ):
services.AddHostedService<StartupHostedService>();
services.AddSingleton<StartupHostedServiceHealthCheck>();
services.AddHealthChecks()
.AddCheck<StartupHostedServiceHealthCheck>(
"hosted_service_startup",
failureStatus: HealthStatus.Degraded,
tags: new[] { "ready" });
services.Configure<HealthCheckPublisherOptions>(options =>
{
options.Delay = TimeSpan.FromSeconds(2);
options.Predicate = (check) => check.Tags.Contains("ready");
});
services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();
Poznámka:
AspNetCore.Diagnostics.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
Slouží MapWhen k podmíněnému větvení kanálu žádosti pro koncové body kontroly stavu.
V následujícím příkladu vytvoří větve kanálu požadavku, aby aktivoval Middleware kontroly stavu, MapWhen
pokud se pro koncový bod obdrží api/HealthCheck
požadavek GET:
app.MapWhen(
context => context.Request.Method == HttpMethod.Get.Method &&
context.Request.Path.StartsWith("/api/HealthCheck"),
builder => builder.UseHealthChecks());
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
Další informace najdete v tématu Middleware ASP.NET Core.
ASP.NET Core nabízí middlewarové kontroly stavu a knihovny pro vytváření sestav stavu komponent infrastruktury aplikací.
Kontroly stavu jsou vystaveny aplikací jako koncové body HTTP. Koncové body kontroly stavu je možné nakonfigurovat pro různé scénáře monitorování v reálném čase:
- Sondy stavu můžou používat orchestrátory kontejnerů a nástroje pro vyrovnávání zatížení ke kontrole stavu aplikace. Orchestrátor kontejnerů může například reagovat na neúspěšnou kontrolu stavu zastavením postupného nasazení nebo restartováním kontejneru. Nástroj pro vyrovnávání zatížení může reagovat na aplikaci, která není v pořádku, směrováním provozu mimo instanci, která selhává, do instance, která je v pořádku.
- Použití paměti, disku a dalších prostředků fyzického serveru je možné monitorovat, aby byl stav v pořádku.
- Kontroly stavu můžou otestovat závislosti aplikace, jako jsou databáze a koncové body externí služby, a ověřit dostupnost a normální fungování.
Zobrazení nebo stažení ukázkového kódu (postup stažení)
Ukázková aplikace obsahuje příklady scénářů popsaných v tomto článku. Pokud chcete spustit ukázkovou aplikaci pro daný scénář, použijte příkaz dotnet run ze složky projektu v příkazovém prostředí. Podrobnosti o používání ukázkové aplikace najdete v souboru ukázkové aplikace README.md
a popisech scénářů v tomto článku.
Požadavky
Kontroly stavu se obvykle používají s externí službou monitorování nebo orchestrátorem kontejnerů ke kontrole stavu aplikace. Než do aplikace přidáte kontroly stavu, rozhodněte se, jaký monitorovací systém se má použít. Monitorovací systém určuje, jaké typy kontrol stavu se mají vytvořit a jak nakonfigurovat jejich koncové body.
Na Microsoft.AspNetCore.Diagnostics.HealthChecks
balíček se implicitně odkazuje pro aplikace ASP.NET Core. Pokud chcete spouštět kontroly stavu pomocí Entity Framework Core, přidejte do balíčku odkaz na Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
balíček.
Ukázková aplikace poskytuje spouštěcí kód, který demonstruje kontroly stavu pro několik scénářů. Scénář sondy databáze kontroluje stav připojení k databázi pomocí AspNetCore.Diagnostics.HealthChecks
. Scénář sondy DbContext kontroluje databázi pomocí .EF CoreDbContext
Pokud chcete prozkoumat databázové scénáře, ukázková aplikace:
- Vytvoří databázi a poskytne její připojovací řetězec v
appsettings.json
souboru. - Obsahuje následující odkazy na balíčky v souboru projektu:
Poznámka:
AspNetCore.Diagnostics.HealthChecks
není udržována ani podporována společností Microsoft.
Další scénář kontroly stavu ukazuje, jak filtrovat kontroly stavu na port pro správu. Ukázková aplikace vyžaduje, Properties/launchSettings.json
abyste vytvořili soubor, který obsahuje adresu URL pro správu a port pro správu. Další informace najdete v části Filtrovat podle portu .
Základní sonda stavu
U mnoha aplikací stačí základní konfigurace sondy stavu, která hlásí dostupnost aplikace pro zpracování požadavků (živé aktivity) ke zjištění stavu aplikace.
Základní konfigurace registruje služby kontroly stavu a volá Middleware kontroly stavu, aby reagoval na koncový bod adresy URL s odpovědí na stav. Ve výchozím nastavení nejsou žádné konkrétní kontroly stavu registrovány k testování žádné konkrétní závislosti nebo subsystému. Aplikace se považuje za v pořádku, pokud může reagovat na adresu URL koncového bodu stavu. Výchozí zapisovač odpovědí zapíše stav (HealthStatus) jako odpověď ve formátu prostého textu zpět klientovi, který označuje HealthStatus.Healthyhodnotu , HealthStatus.Degradednebo HealthStatus.Unhealthy stav.
Zaregistrujte služby kontroly stavu v adresáři AddHealthChecks Startup.ConfigureServices
. Vytvořte koncový bod kontroly stavu voláním MapHealthChecks
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
Vytváření kontrol stavu
Kontroly stavu se vytvářejí implementací IHealthCheck rozhraní. Metoda CheckHealthAsync vrátí HealthCheckResult hodnotu, která označuje stav jako Healthy
, Degraded
nebo Unhealthy
. Výsledek se zapíše jako odpověď prostého textu s konfigurovatelným stavovým kódem (konfigurace je popsaná v části Možnosti kontroly stavu). HealthCheckResult může také vracet volitelné páry klíč-hodnota.
Následující ExampleHealthCheck
třída ukazuje rozložení kontroly stavu. Logika kontroly stavu je umístěna CheckHealthAsync
v metodě. Následující příklad nastaví fiktivní proměnnou , healthCheckResultHealthy
na true
. Pokud je hodnota healthCheckResultHealthy
nastavena na false
, HealthCheckResult.Unhealthy
stav se vrátí.
public class ExampleHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default(CancellationToken))
{
var healthCheckResultHealthy = true;
if (healthCheckResultHealthy)
{
return Task.FromResult(
HealthCheckResult.Healthy("A healthy result."));
}
return Task.FromResult(
HealthCheckResult.Unhealthy("An unhealthy result."));
}
}
Registrace služeb kontroly stavu
Typ ExampleHealthCheck
se přidá ke službám kontroly stavu s následujícími položkami AddCheck Startup.ConfigureServices
:
services.AddHealthChecks()
.AddCheck<ExampleHealthCheck>("example_health_check");
Přetížení AddCheck zobrazené v následujícím příkladu nastaví stav selhání (HealthStatus) tak, aby ohlásil, když kontrola stavu hlásí selhání. Pokud je stav selhání nastavený na null
(výchozí), HealthStatus.Unhealthy je hlášeno. Toto přetížení je užitečný scénář pro autory knihoven, kde je stav selhání označený knihovnou vynucen aplikací, když dojde k selhání kontroly stavu, pokud implementace kontroly stavu dodržuje nastavení.
Značky lze použít k filtrování kontrol stavu (popsáno dále v části Kontroly stavu filtru).
services.AddHealthChecks()
.AddCheck<ExampleHealthCheck>(
"example_health_check",
failureStatus: HealthStatus.Degraded,
tags: new[] { "example" });
AddCheck může také spustit funkci lambda. V následujícím příkladu je název kontroly stavu zadán jako Example
a kontrola vždy vrátí stav v pořádku:
services.AddHealthChecks()
.AddCheck("Example", () =>
HealthCheckResult.Healthy("Example is OK!"), tags: new[] { "example" });
Volání AddTypeActivatedCheck pro předání argumentů implementaci kontroly stavu V následujícím příkladu TestHealthCheckWithArgs
přijímá celé číslo a řetězec pro použití, pokud CheckHealthAsync je volán:
private class TestHealthCheckWithArgs : IHealthCheck
{
public TestHealthCheckWithArgs(int i, string s)
{
I = i;
S = s;
}
public int I { get; set; }
public string S { get; set; }
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context,
CancellationToken cancellationToken = default)
{
...
}
}
TestHealthCheckWithArgs
je registrován voláním AddTypeActivatedCheck
celého čísla a řetězce předaného implementaci:
services.AddHealthChecks()
.AddTypeActivatedCheck<TestHealthCheckWithArgs>(
"test",
failureStatus: HealthStatus.Degraded,
tags: new[] { "example" },
args: new object[] { 5, "string" });
Použití směrování kontrol stavu
MapHealthChecks
Volání Startup.Configure
tvůrce koncových bodů pomocí adresy URL koncového bodu nebo relativní cesty:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
});
Vyžadovat hostitele
Volání RequireHost
pro zadání jednoho nebo více povolených hostitelů pro koncový bod kontroly stavu Hostitelé by měli mít místo punycode kódování Unicode a můžou obsahovat port. Pokud kolekci nezadáte, přijme se žádný hostitel.
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health").RequireHost("www.contoso.com:5001");
});
Další informace najdete v části Filtrovat podle portu .
Vyžadovat autorizaci
Volání RequireAuthorization
pro spuštění autorizačního middlewaru na koncovém bodu žádosti o kontrolu stavu RequireAuthorization
Přetížení přijímá jednu nebo více zásad autorizace. Pokud zásady nejsou zadané, použijí se výchozí zásady autorizace.
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health").RequireAuthorization();
});
Povolení žádostí nepůvodního zdroje (CORS)
I když spouštění kontrol stavu ručně z prohlížeče není běžným scénářem použití, middleware CORS je možné povolit voláním RequireCors
koncových bodů kontrol stavu. RequireCors
Přetížení přijímá delegátaCorsPolicyBuilder
() nebo název zásady CORS. Pokud zásady nejsou zadané, použije se výchozí zásada CORS. Další informace najdete v tématu Povolení žádostí mezi zdroji (CORS) v ASP.NET Core.
Možnosti kontroly stavu
HealthCheckOptions poskytnout příležitost přizpůsobit chování kontroly stavu:
- Filtrování kontrol stavu
- Přizpůsobení stavového kódu HTTP
- Potlačení hlaviček mezipaměti
- Přizpůsobení výstupu
Filtrování kontrol stavu
Ve výchozím nastavení spustí Middleware kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která vrátí logickou hodnotu možnosti Predicate . V následujícím příkladu Bar
se kontrola stavu vyfiltruje podle značky (bar_tag
) v podmíněném příkazu funkce, kde true
se vrátí pouze v případě, že se vlastnost kontroly Tags stavu shoduje foo_tag
nebo baz_tag
:
V Startup.ConfigureServices
:
services.AddHealthChecks()
.AddCheck("Foo", () =>
HealthCheckResult.Healthy("Foo is OK!"), tags: new[] { "foo_tag" })
.AddCheck("Bar", () =>
HealthCheckResult.Unhealthy("Bar is unhealthy!"), tags: new[] { "bar_tag" })
.AddCheck("Baz", () =>
HealthCheckResult.Healthy("Baz is OK!"), tags: new[] { "baz_tag" });
Vyfiltruje Startup.Configure
Predicate
kontrolu stavu panelu. Pouze Foo a Baz provést:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
Predicate = (check) => check.Tags.Contains("foo_tag") ||
check.Tags.Contains("baz_tag")
});
});
Přizpůsobení stavového kódu HTTP
Slouží ResultStatusCodes k přizpůsobení mapování stavu na stavové kódy HTTP. Následující StatusCodes přiřazení jsou výchozí hodnoty používané middlewarem. Změňte hodnoty stavového kódu tak, aby splňovaly vaše požadavky.
V Startup.Configure
:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
}
});
});
Potlačení hlaviček mezipaměti
AllowCachingResponses určuje, zda middleware kontroly stavu přidává hlavičky HTTP do odpovědi sondy, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je false
hodnota (výchozí), middleware nastaví nebo přepíše Cache-Control
Expires
, a Pragma
hlavičky, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je true
hodnota, middleware neupraví hlavičky mezipaměti odpovědi.
V Startup.Configure
:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
AllowCachingResponses = true
});
});
Přizpůsobení výstupu
Nastavte Startup.Configure
možnost HealthCheckOptions.ResponseWriter delegáta pro zápis odpovědi:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
ResponseWriter = WriteResponse
});
});
Výchozí delegát zapíše minimální odpověď prostého textu s řetězcovou hodnotou HealthReport.Status
. Následující vlastní delegáti vypíše vlastní odpověď 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 SYSTEM_TEXT_JSON
, aby bylo možné povolit Newtonsoft.Json
verzi WriteResponse
. CustomWriterStartup.cs
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.
Sonda databáze
Kontrola stavu může zadat databázový dotaz, který se má spustit jako logický test, který indikuje, jestli databáze normálně reaguje.
Ukázková aplikace používá AspNetCore.Diagnostics.HealthChecks
knihovnu kontroly stavu pro aplikace ASP.NET Core ke spuštění kontroly stavu 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.
Upozorňující
Při kontrole připojení k databázi s dotazem zvolte dotaz, který se rychle vrátí. Přístup k dotazům riskuje přetížení databáze a snížení výkonu. Ve většině případů není spuštění testovacího dotazu nutné. Stačí pouze úspěšné připojení k databázi. Pokud zjistíte, že je nutné spustit dotaz, zvolte jednoduchý dotaz SELECT, například SELECT 1
.
Zahrnout odkaz na AspNetCore.HealthChecks.SqlServer
balíček .
Do souboru ukázkové aplikace zadejte platný připojovací řetězec appsettings.json
databáze. Aplikace používá databázi SQL Serveru s názvem HealthCheckSample
:
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=HealthCheckSample;Trusted_Connection=True;MultipleActiveResultSets=true;ConnectRetryCount=0"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
},
"Console": {
"IncludeScopes": "true"
}
},
"AllowedHosts": "*"
}
Zaregistrujte služby kontroly stavu v adresáři AddHealthChecks Startup.ConfigureServices
. Ukázková aplikace volá metodu AddSqlServer
s připojovací řetězec databáze (DbHealthStartup.cs
):
services.AddHealthChecks()
.AddSqlServer(Configuration["ConnectionStrings:DefaultConnection"]);
Koncový bod kontroly stavu se vytvoří voláním MapHealthChecks
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
Poznámka:
AspNetCore.Diagnostics.HealthChecks
není udržována ani podporována společností Microsoft.
Sonda Entity Framework Core DbContext
Kontrola DbContext
potvrzuje, že aplikace může komunikovat s databází nakonfigurovanou pro aplikaci EF CoreDbContext
. Kontrola je podporovaná DbContext
v aplikacích, které:
- Použijte Entity Framework (EF) Core.
- Zahrnout odkaz na
Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
balíček .
AddDbContextCheck<TContext>
zaregistruje kontrolu stavu pro DbContext
Tato DbContext
metoda je zadána TContext
jako metoda. K dispozici je přetížení ke konfiguraci stavu selhání, značek a vlastního testovacího dotazu.
Standardně:
- EF Core
CanConnectAsync
VoláníDbContextHealthCheck
metody. Můžete přizpůsobit, jakou operaci se spustí při kontrole stavu pomocíAddDbContextCheck
přetížení metod. - Název kontroly stavu je název
TContext
typu.
V ukázkové aplikaci AppDbContext
se poskytuje AddDbContextCheck
a zaregistruje jako služba v Startup.ConfigureServices
:DbContextHealthStartup.cs
services.AddHealthChecks()
.AddDbContextCheck<AppDbContext>();
services.AddDbContext<AppDbContext>(options =>
{
options.UseSqlServer(
Configuration["ConnectionStrings:DefaultConnection"]);
});
Koncový bod kontroly stavu se vytvoří voláním MapHealthChecks
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í řetězec v instanci SQL Serveru neexistuje. Pokud databáze existuje, odstraňte ji.
V příkazovém prostředí spusťte následující příkaz ze složky projektu:
dotnet run --scenario dbcontext
Po spuštění aplikace zkontrolujte stav provedením požadavku na /health
koncový bod v prohlížeči. Databáze a AppDbContext
neexistuje, takže aplikace poskytuje následující odpověď:
Unhealthy
Aktivujte ukázkovou aplikaci a vytvořte databázi. Vytvořte žádost na /createdatabase
. Aplikace reaguje:
Creating the database...
Done!
Navigate to /health to see the health status.
Vytvořte požadavek na /health
koncový bod. Databáze a kontext existují, takže aplikace reaguje:
Healthy
Aktivujte ukázkovou aplikaci, aby se databáze odstranila. Vytvořte žádost na /deletedatabase
. Aplikace reaguje:
Deleting the database...
Done!
Navigate to /health to see the health status.
Vytvořte požadavek na /health
koncový bod. Aplikace poskytuje odpověď, která není v pořádku:
Unhealthy
Samostatné testy připravenosti a aktivity
V některých scénářích hostování se k rozlišení dvou stavů aplikace používá pár kontrol stavu:
- Připravenost označuje, jestli aplikace běží normálně, ale není připravená přijímat žádosti.
- Liveness označuje, jestli se aplikace chybově ukončila a musí se restartovat.
Představte si následující příklad: Aplikace musí stáhnout velký konfigurační soubor, než bude připraven zpracovávat požadavky. Nechceme, aby se aplikace restartovala, pokud se počáteční stahování nezdaří, protože aplikace může několikrát zkusit stáhnout soubor znovu. K popisu aktivity procesu používáme sondu živé aktivity, nespustíme žádné další kontroly. Chceme také zabránit tomu, aby se žádosti odesílaly do aplikace před úspěšným stažením konfiguračního souboru. Sondu připravenosti použijeme k označení stavu "nepřipraveno", dokud stahování nebude úspěšné a aplikace bude připravená přijímat žádosti.
Ukázková aplikace obsahuje kontrolu stavu, která hlásí dokončení dlouhotrvající spouštěcí úlohy v hostované službě. Zpřístupňuje StartupHostedServiceHealthCheck
vlastnost, StartupTaskCompleted
kterou hostovaná služba může nastavit na true
po dokončení dlouhotrvající úlohy (StartupHostedServiceHealthCheck.cs
):
public class StartupHostedServiceHealthCheck : IHealthCheck
{
private volatile bool _startupTaskCompleted = false;
public string Name => "slow_dependency_check";
public bool StartupTaskCompleted
{
get => _startupTaskCompleted;
set => _startupTaskCompleted = value;
}
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default(CancellationToken))
{
if (StartupTaskCompleted)
{
return Task.FromResult(
HealthCheckResult.Healthy("The startup task is finished."));
}
return Task.FromResult(
HealthCheckResult.Unhealthy("The startup task is still running."));
}
}
Dlouhotrvající úloha na pozadí je spuštěna hostované službou (Services/StartupHostedService
). Na závěr úkolu StartupHostedServiceHealthCheck.StartupTaskCompleted
je nastaveno:true
public class StartupHostedService : IHostedService, IDisposable
{
private readonly int _delaySeconds = 15;
private readonly ILogger _logger;
private readonly StartupHostedServiceHealthCheck _startupHostedServiceHealthCheck;
public StartupHostedService(ILogger<StartupHostedService> logger,
StartupHostedServiceHealthCheck startupHostedServiceHealthCheck)
{
_logger = logger;
_startupHostedServiceHealthCheck = startupHostedServiceHealthCheck;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Startup Background Service is starting.");
// Simulate the effect of a long-running startup task.
Task.Run(async () =>
{
await Task.Delay(_delaySeconds * 1000);
_startupHostedServiceHealthCheck.StartupTaskCompleted = true;
_logger.LogInformation("Startup Background Service has started.");
});
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Startup Background Service is stopping.");
return Task.CompletedTask;
}
public void Dispose()
{
}
}
Kontrola stavu je zaregistrovaná AddCheck Startup.ConfigureServices
společně s hostovanými službami. Vzhledem k tomu, že hostovaná služba musí nastavit vlastnost kontroly stavu, je kontrola stavu také zaregistrovaná v kontejneru služby (LivenessProbeStartup.cs
):
services.AddHostedService<StartupHostedService>();
services.AddSingleton<StartupHostedServiceHealthCheck>();
services.AddHealthChecks()
.AddCheck<StartupHostedServiceHealthCheck>(
"hosted_service_startup",
failureStatus: HealthStatus.Degraded,
tags: new[] { "ready" });
services.Configure<HealthCheckPublisherOptions>(options =>
{
options.Delay = TimeSpan.FromSeconds(2);
options.Predicate = (check) => check.Tags.Contains("ready");
});
services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();
Koncový bod kontroly stavu se vytvoří voláním MapHealthChecks
Startup.Configure
. V ukázkové aplikaci se koncové body kontroly stavu vytvoří na adrese:
/health/ready
pro kontrolu připravenosti. Kontrola připravenosti filtruje kontroly stavu na kontrolu stavu pomocí značkyready
./health/live
pro kontrolu živého života. Kontrola aktivity filtrujeStartupHostedServiceHealthCheck
vrácenímfalse
se změnami (další informace najdete vHealthCheckOptions.Predicate
tématu Kontroly stavu filtru).
V následujícím příkladu kódu:
- Kontrola připravenosti používá všechny registrované kontroly se značkou Připraveno.
- Vyloučí
Predicate
všechny kontroly a vrátí hodnotu 200-OK.
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions()
{
Predicate = (check) => check.Tags.Contains("ready"),
});
endpoints.MapHealthChecks("/health/live", new HealthCheckOptions()
{
Predicate = (_) => false
});
}
Pokud chcete spustit scénář konfigurace připravenosti a aktivity pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:
dotnet run --scenario liveness
V prohlížeči navštivte /health/ready
několikrát, dokud nepřejde 15 sekund. Kontrola stavu hlásí Unhealthy
prvních 15 sekund. Po 15 sekundách koncový bod hlásí Healthy
dokončení dlouhotrvající úlohy hostované služby.
Tento příklad také vytvoří vydavatele kontroly stavu (IHealthCheckPublisher implementaci), který spustí první kontrolu připravenosti se dvěma sekundami zpoždění. Další informace najdete v části Vydavatele kontroly stavu.
Příklad Kubernetes
Použití samostatných kontrol připravenosti a aktivity je užitečné v prostředí, jako je Kubernetes. V Kubernetes může být aplikace nutná ke spouštění časově náročných spouštěcích prací před přijetím požadavků, jako je například test dostupnosti podkladové databáze. Použití samostatných kontrol umožňuje orchestrátoru rozlišit, jestli aplikace funguje, ale ještě není připravená nebo jestli se aplikaci nepodařilo spustit. Další informace o testech připravenosti a aktivity v Kubernetes najdete v dokumentaci ke konfiguraci testů živé aktivity a připravenosti v Kubernetes.
Následující příklad ukazuje konfiguraci sondy připravenosti Kubernetes:
spec:
template:
spec:
readinessProbe:
# an http probe
httpGet:
path: /health/ready
port: 80
# length of time to wait for a pod to initialize
# after pod startup, before applying health checking
initialDelaySeconds: 30
timeoutSeconds: 1
ports:
- containerPort: 80
Sonda založená na metrikách s vlastním zapisovačem odpovědí
Ukázková aplikace ukazuje kontrolu stavu paměti pomocí vlastního zapisovače odpovědí.
MemoryHealthCheck
hlásí snížený stav, pokud aplikace používá více než danou prahovou hodnotu paměti (1 GB v ukázkové aplikaci). Obsahuje HealthCheckResult informace o uvolňování paměti (GC) pro aplikaci (MemoryHealthCheck.cs
):
public class MemoryHealthCheck : IHealthCheck
{
private readonly IOptionsMonitor<MemoryCheckOptions> _options;
public MemoryHealthCheck(IOptionsMonitor<MemoryCheckOptions> options)
{
_options = options;
}
public string Name => "memory_check";
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default(CancellationToken))
{
var options = _options.Get(context.Registration.Name);
// Include GC information in the reported diagnostics.
var allocated = GC.GetTotalMemory(forceFullCollection: false);
var data = new Dictionary<string, object>()
{
{ "AllocatedBytes", allocated },
{ "Gen0Collections", GC.CollectionCount(0) },
{ "Gen1Collections", GC.CollectionCount(1) },
{ "Gen2Collections", GC.CollectionCount(2) },
};
var status = (allocated < options.Threshold) ?
HealthStatus.Healthy : context.Registration.FailureStatus;
return Task.FromResult(new HealthCheckResult(
status,
description: "Reports degraded status if allocated bytes " +
$">= {options.Threshold} bytes.",
exception: null,
data: data));
}
}
Zaregistrujte služby kontroly stavu v adresáři AddHealthChecks 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 CustomWriterStartup.cs
ukázkové aplikaci:
services.AddHealthChecks()
.AddMemoryHealthCheck("memory");
Koncový bod kontroly stavu se vytvoří voláním MapHealthChecks
Startup.Configure
. Delegát WriteResponse
je k dispozici vlastnosti pro ResponseWriter výstup vlastní odpovědi JSON při spuštění 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
Poznámka:
AspNetCore.Diagnostics.HealthChecks
zahrnuje scénáře kontroly stavu na základě metrik, včetně diskového úložiště a kontroly maximální hodnoty liveness.
AspNetCore.Diagnostics.HealthChecks
není udržována ani podporována společností Microsoft.
Filtrovat podle portu
MapHealthChecks
Volání RequireHost
se vzorem adresy URL, který určuje port, který omezí požadavky kontroly stavu na zadaný port. Tento přístup se obvykle používá v prostředí kontejneru k vystavení portu pro monitorovací služby.
Ukázková aplikace nakonfiguruje port pomocí zprostředkovatele konfigurace proměnné prostředí. Port se nastaví v launchSettings.json
souboru a předá zprostředkovateli konfigurace prostřednictvím proměnné prostředí. Musíte také nakonfigurovat server tak, aby naslouchal požadavkům na portu pro správu.
Pokud chcete ukázkovou aplikaci použít k předvedení konfigurace portů pro správu, vytvořte launchSettings.json
soubor ve Properties
složce.
Následující Properties/launchSettings.json
soubor v ukázkové aplikaci není součástí souborů projektu ukázkové aplikace a musí být vytvořen ručně:
{
"profiles": {
"SampleApp": {
"commandName": "Project",
"commandLineArgs": "",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_URLS": "http://localhost:5000/;http://localhost:5001/",
"ASPNETCORE_MANAGEMENTPORT": "5001"
},
"applicationUrl": "http://localhost:5000/"
}
}
}
Zaregistrujte služby kontroly stavu v adresáři AddHealthChecks Startup.ConfigureServices
. Vytvořte koncový bod kontroly stavu voláním MapHealthChecks
Startup.Configure
.
V ukázkové aplikaci volání RequireHost
koncového bodu určuje Startup.Configure
port pro správu z konfigurace:
endpoints.MapHealthChecks("/health")
.RequireHost($"*:{Configuration["ManagementPort"]}");
Koncové body se vytvoří v ukázkové aplikaci v Startup.Configure
aplikaci . V následujícím příkladu kódu:
- Kontrola připravenosti používá všechny registrované kontroly se značkou Připraveno.
- Vyloučí
Predicate
všechny kontroly a vrátí hodnotu 200-OK.
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions()
{
Predicate = (check) => check.Tags.Contains("ready"),
});
endpoints.MapHealthChecks("/health/live", new HealthCheckOptions()
{
Predicate = (_) => false
});
}
Poznámka:
V ukázkové aplikaci se můžete vyhnout vytváření launchSettings.json
souboru nastavením portu pro správu explicitně v kódu. V Program.cs
místě vytvoření HostBuilder přidejte volání ListenAnyIP a zadejte koncový bod portu pro správu aplikace. V Configure
poli ManagementPortStartup.cs
, zadejte port pro správu pomocí RequireHost
:
Program.cs
:
return new HostBuilder()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseKestrel()
.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5001);
})
.UseStartup(startupType);
})
.Build();
ManagementPortStartup.cs
:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health").RequireHost("*:5001");
});
Pokud chcete spustit scénář konfigurace portu pro správu pomocí ukázkové aplikace, spusťte následující příkaz ze složky projektu v příkazovém prostředí:
dotnet run --scenario port
Distribuce knihovny kontroly stavu
Distribuce kontroly stavu jako knihovny:
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
CheckHealthAsync
kontrol stavu :data1
adata2
používají se v metodě ke spuštění logiky kontroly stavu sondy.AccessViolationException
zpracovává se.
Když dojde k chyběAccessViolationException, vrátí HealthCheckResult se funkce umožňující FailureStatus uživatelům konfigurovat stav selhání kontrol stavu.
using System; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Diagnostics.HealthChecks; namespace SampleApp { public class ExampleHealthCheck : IHealthCheck { private readonly string _data1; private readonly int? _data2; public ExampleHealthCheck(string data1, int? data2) { _data1 = data1 ?? throw new ArgumentNullException(nameof(data1)); _data2 = data2 ?? throw new ArgumentNullException(nameof(data2)); } public async Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken) { try { return HealthCheckResult.Healthy(); } catch (AccessViolationException ex) { return new HealthCheckResult( context.Registration.FailureStatus, description: "An access violation occurred during the check.", exception: ex, data: null); } } } }
Napište metodu rozšíření s parametry, které spotřebová aplikace volá ve své
Startup.Configure
metodě. V následujícím příkladu předpokládejme následující podpis metody kontroly stavu:ExampleHealthCheck(string, string, int )
Předchozí podpis označuje, že
ExampleHealthCheck
vyžaduje další data ke zpracování logiky sondy kontroly stavu. Data se poskytují delegátu použitému k vytvoření instance kontroly stavu při registraci kontroly stavu v metodě rozšíření. V následujícím příkladu volající určuje volitelné:- název kontroly stavu (
name
). Pokudnull
se použije ,example_health_check
použije se. - datový bod řetězce pro kontrolu stavu (
data1
). - celočíselné datové body pro kontrolu stavu (
data2
). Pokudnull
se použije ,1
použije se. - stav selhání (HealthStatus). Výchozí hodnota je
null
. HealthStatus.Unhealthy Pokudnull
se zobrazí stav selhání, zobrazí se zpráva. - značky (
IEnumerable<string>
).
using System.Collections.Generic; using Microsoft.Extensions.Diagnostics.HealthChecks; public static class ExampleHealthCheckBuilderExtensions { const string DefaultName = "example_health_check"; public static IHealthChecksBuilder AddExampleHealthCheck( this IHealthChecksBuilder builder, string name = default, string data1, int data2 = 1, HealthStatus? failureStatus = default, IEnumerable<string> tags = default) { return builder.Add(new HealthCheckRegistration( name ?? DefaultName, sp => new ExampleHealthCheck(data1, data2), failureStatus, tags)); } }
- název kontroly stavu (
Kontrola stavu – Vydavatel
IHealthCheckPublisher Po přidání do kontejneru služby systém kontroly stavu pravidelně provádí kontroly stavu a volání PublishAsync
s výsledkem. To je užitečné ve scénáři systému monitorování stavu založeného na nabízených oznámeních, který očekává, že každý proces bude pravidelně volat monitorovací systém, aby zjistil stav.
Rozhraní IHealthCheckPublisher má jednu metodu:
Task PublishAsync(HealthReport report, CancellationToken cancellationToken);
HealthCheckPublisherOptions povolit nastavení:
- Delay: Počáteční prodleva použitá po spuštění aplikace před spuštěním IHealthCheckPublisher instancí. Zpoždění se použije jednou při spuštění a nevztahuje se na následné iterace. Výchozí hodnota je pět sekund.
- Period: Období IHealthCheckPublisher provádění. Výchozí hodnota je 30 sekund.
- Predicate: Pokud Predicate je
null
(výchozí), spustí služba vydavatele kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která filtruje sadu kontrol. Predikát se vyhodnocuje každé období. - Timeout: Časový limit pro provádění kontrol stavu pro všechny IHealthCheckPublisher instance. Slouží InfiniteTimeSpan ke spuštění bez časového limitu. Výchozí hodnota je 30 sekund.
V ukázkové aplikaci ReadinessPublisher
je IHealthCheckPublisher implementace. Stav kontroly stavu se protokoluje pro každou kontrolu na úrovni protokolu:
- Informace (LogInformation) pokud je Healthystav kontroly stavu .
- Chyba (LogError) pokud je stav nebo Degraded Unhealthy.
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 LivenessProbeStartup
StartupHostedService
ukázkové aplikace má kontrola připravenosti dvě sekundy zpoždění spuštění a spustí kontrolu každých 30 sekund. K aktivaci IHealthCheckPublisher implementace se ukázka zaregistruje ReadinessPublisher
jako jednoúčelová služba v kontejneru injektáže závislostí (DI ):
services.AddHostedService<StartupHostedService>();
services.AddSingleton<StartupHostedServiceHealthCheck>();
services.AddHealthChecks()
.AddCheck<StartupHostedServiceHealthCheck>(
"hosted_service_startup",
failureStatus: HealthStatus.Degraded,
tags: new[] { "ready" });
services.Configure<HealthCheckPublisherOptions>(options =>
{
options.Delay = TimeSpan.FromSeconds(2);
options.Predicate = (check) => check.Tags.Contains("ready");
});
services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();
Poznámka:
AspNetCore.Diagnostics.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
Slouží MapWhen k podmíněnému větvení kanálu žádosti pro koncové body kontroly stavu.
V následujícím příkladu vytvoří větve kanálu požadavku, aby aktivoval Middleware kontroly stavu, MapWhen
pokud se pro koncový bod obdrží api/HealthCheck
požadavek GET:
app.MapWhen(
context => context.Request.Method == HttpMethod.Get.Method &&
context.Request.Path.StartsWith("/api/HealthCheck"),
builder => builder.UseHealthChecks());
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
Další informace najdete v tématu Middleware ASP.NET Core.
ASP.NET Core nabízí middlewarové kontroly stavu a knihovny pro vytváření sestav stavu komponent infrastruktury aplikací.
Kontroly stavu jsou vystaveny aplikací jako koncové body HTTP. Koncové body kontroly stavu je možné nakonfigurovat pro různé scénáře monitorování v reálném čase:
- Sondy stavu můžou používat orchestrátory kontejnerů a nástroje pro vyrovnávání zatížení ke kontrole stavu aplikace. Orchestrátor kontejnerů může například reagovat na neúspěšnou kontrolu stavu zastavením postupného nasazení nebo restartováním kontejneru. Nástroj pro vyrovnávání zatížení může reagovat na aplikaci, která není v pořádku, směrováním provozu mimo instanci, která selhává, do instance, která je v pořádku.
- Použití paměti, disku a dalších prostředků fyzického serveru je možné monitorovat, aby byl stav v pořádku.
- Kontroly stavu můžou otestovat závislosti aplikace, jako jsou databáze a koncové body externí služby, a ověřit dostupnost a normální fungování.
Kontroly stavu se obvykle používají s externí službou monitorování nebo orchestrátorem kontejnerů ke kontrole stavu aplikace. Než do aplikace přidáte kontroly stavu, rozhodněte se, jaký monitorovací systém se má použít. Monitorovací systém určuje, jaké typy kontrol stavu se mají vytvořit a jak nakonfigurovat jejich koncové body.
Základní sonda stavu
U mnoha aplikací stačí základní konfigurace sondy stavu, která hlásí dostupnost aplikace pro zpracování požadavků (živé aktivity) ke zjištění stavu aplikace.
Základní konfigurace registruje služby kontroly stavu a volá Middleware kontroly stavu, aby reagoval na koncový bod adresy URL s odpovědí na stav. Ve výchozím nastavení nejsou žádné konkrétní kontroly stavu registrovány k testování žádné konkrétní závislosti nebo subsystému. Aplikace se považuje za v pořádku, pokud může reagovat na adresu URL koncového bodu stavu. Výchozí zapisovač odpovědí zapíše HealthStatus jako odpověď prostého textu klientovi. Je HealthStatus
HealthStatus.Healthyto , HealthStatus.Degradednebo HealthStatus.Unhealthy.
Zaregistrujte služby kontroly stavu v adresáři AddHealthChecks Program.cs
. Vytvořte koncový bod kontroly stavu voláním MapHealthChecks.
Následující příklad vytvoří koncový bod kontroly stavu na /healthz
adrese:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks();
var app = builder.Build();
app.MapHealthChecks("/healthz");
app.Run();
DockeruHEALTHCHECK
Docker nabízí integrovanou HEALTHCHECK
direktivu, která se dá použít ke kontrole stavu aplikace, která používá základní konfiguraci kontroly stavu:
HEALTHCHECK CMD curl --fail http://localhost:5000/healthz || exit
Předchozí příklad používá curl
k vytvoření požadavku HTTP na koncový bod kontroly stavu na /healthz
adrese . curl
není součástí imagí kontejneru .NET Linux, ale dá se přidat instalací požadovaného balíčku do souboru Dockerfile. Kontejnery, které používají image založené na Alpine Linuxu, můžou místo zahrnutí wget
curl
použít .
Vytváření kontrol stavu
Kontroly stavu se vytvářejí implementací IHealthCheck rozhraní. Metoda CheckHealthAsync vrátí HealthCheckResult hodnotu, která označuje stav jako Healthy
, Degraded
nebo Unhealthy
. Výsledek se zapíše jako odpověď ve formátu prostého textu s konfigurovatelným stavovým kódem. Konfigurace je popsaná v části Možnosti kontroly stavu. HealthCheckResult může také vracet volitelné páry klíč-hodnota.
Následující příklad ukazuje rozložení kontroly stavu:
public class SampleHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context, CancellationToken cancellationToken = default)
{
var isHealthy = true;
// ...
if (isHealthy)
{
return Task.FromResult(
HealthCheckResult.Healthy("A healthy result."));
}
return Task.FromResult(
new HealthCheckResult(
context.Registration.FailureStatus, "An unhealthy result."));
}
}
Logika kontroly stavu je umístěna v CheckHealthAsync metodě. Předchozí příklad nastaví fiktivní proměnnou , isHealthy
na true
. Pokud je hodnota isHealthy
nastavena na false
, HealthCheckRegistration.FailureStatus stav se vrátí.
Pokud CheckHealthAsync při kontrole vyvolá výjimku, vrátí se nová HealthReportEntry hodnota s nastavenou HealthReportEntry.Status na FailureStatushodnotu . Tento stav je definován ( AddCheck viz část Služby kontroly stavu) a obsahuje vnitřní výjimku , která způsobila selhání kontroly. Je Description nastavená na zprávu výjimky.
Registrace služeb kontroly stavu
Pokud chcete zaregistrovat službu kontroly stavu, zavolejte AddCheck do Program.cs
:
builder.Services.AddHealthChecks()
.AddCheck<SampleHealthCheck>("Sample");
Přetížení AddCheck zobrazené v následujícím příkladu nastaví stav selhání (HealthStatus) tak, aby ohlásil, když kontrola stavu hlásí selhání. Pokud je stav selhání nastavený na null
(výchozí), HealthStatus.Unhealthy je hlášeno. Toto přetížení je užitečný scénář pro autory knihoven, kde je stav selhání označený knihovnou vynucen aplikací, když dojde k selhání kontroly stavu, pokud implementace kontroly stavu dodržuje nastavení.
Značky lze použít k filtrování kontrol stavu. Značky jsou popsány v části Kontroly stavu filtru.
builder.Services.AddHealthChecks()
.AddCheck<SampleHealthCheck>(
"Sample",
failureStatus: HealthStatus.Degraded,
tags: new[] { "sample" });
AddCheck může také spustit funkci lambda. V následujícím příkladu vrátí kontrola stavu vždy výsledek, který je v pořádku:
builder.Services.AddHealthChecks()
.AddCheck("Sample", () => HealthCheckResult.Healthy("A healthy result."));
Volání AddTypeActivatedCheck pro předání argumentů implementaci kontroly stavu V následujícím příkladu přijímá kontrola stavu aktivovaná typem celé číslo a řetězec v jeho konstruktoru:
public class SampleHealthCheckWithArgs : IHealthCheck
{
private readonly int _arg1;
private readonly string _arg2;
public SampleHealthCheckWithArgs(int arg1, string arg2)
=> (_arg1, _arg2) = (arg1, arg2);
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context, CancellationToken cancellationToken = default)
{
// ...
return Task.FromResult(HealthCheckResult.Healthy("A healthy result."));
}
}
Pokud chcete zaregistrovat předchozí kontrolu stavu, zavolejte AddTypeActivatedCheck
celé číslo a řetězec předaný jako argumenty:
builder.Services.AddHealthChecks()
.AddTypeActivatedCheck<SampleHealthCheckWithArgs>(
"Sample",
failureStatus: HealthStatus.Degraded,
tags: new[] { "sample" },
args: new object[] { 1, "Arg" });
Použití směrování kontrol stavu
MapHealthChecks
Volání Program.cs
tvůrce koncových bodů pomocí adresy URL koncového bodu nebo relativní cesty:
app.MapHealthChecks("/healthz");
Vyžadovat hostitele
Volání RequireHost
pro zadání jednoho nebo více povolených hostitelů pro koncový bod kontroly stavu Hostitelé by měli mít místo punycode kódování Unicode a můžou obsahovat port. Pokud kolekci nezadáte, přijme se žádný hostitel:
app.MapHealthChecks("/healthz")
.RequireHost("www.contoso.com:5001");
Chcete-li omezit koncový bod kontroly stavu tak, aby reagoval pouze na konkrétním portu, zadejte port v volání RequireHost
. Tento přístup se obvykle používá v prostředí kontejneru k zveřejnění portu pro monitorovací služby:
app.MapHealthChecks("/healthz")
.RequireHost("*:5001");
Upozorňující
Rozhraní API, které závisí na hlavičce hostitele, například HttpRequest.Host a RequireHost, podléhají potenciálnímu falšování identity klienty.
Pokud chcete zabránit falšování identity hostitele a portu, použijte jeden z následujících přístupů:
- Použijte HttpContext.Connection (ConnectionInfo.LocalPort) místo, kde jsou porty kontrolovány.
- Používejte filtrování hostitelů.
Pokud chcete zabránit neoprávněným klientům v falšování identity portu, zavolejte RequireAuthorization:
app.MapHealthChecks("/healthz")
.RequireHost("*:5001")
.RequireAuthorization();
Další informace naleznete v tématu Porovnávání hostitelů v trasách s RequireHost.
Vyžadovat autorizaci
Volání RequireAuthorization pro spuštění autorizačního middlewaru na koncovém bodu žádosti o kontrolu stavu RequireAuthorization
Přetížení přijímá jednu nebo více zásad autorizace. Pokud zásady nejsou zadané, použije se výchozí zásada autorizace:
app.MapHealthChecks("/healthz")
.RequireAuthorization();
Povolení žádostí nepůvodního zdroje (CORS)
I když spouštění kontrol stavu ručně z prohlížeče není běžným scénářem, middleware CORS je možné povolit voláním RequireCors
koncových bodů kontrol stavu. Přetížení RequireCors
přijímá delegáta tvůrce zásad CORS (CorsPolicyBuilder
) nebo název zásady. Další informace najdete v tématu Povolení žádostí mezi zdroji (CORS) v ASP.NET Core.
Možnosti kontroly stavu
HealthCheckOptions poskytnout příležitost přizpůsobit chování kontroly stavu:
- Filtrování kontrol stavu
- Přizpůsobení stavového kódu HTTP
- Potlačení hlaviček mezipaměti
- Přizpůsobení výstupu
Filtrování kontrol stavu
Ve výchozím nastavení spustí Middleware kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která vrátí logickou hodnotu možnosti Predicate .
Následující příklad filtruje kontroly stavu tak, aby se spustily pouze ty, které jsou označené jako spuštěné sample
:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
Predicate = healthCheck => healthCheck.Tags.Contains("sample")
});
Přizpůsobení stavového kódu HTTP
Slouží ResultStatusCodes k přizpůsobení mapování stavu na stavové kódy HTTP. Následující StatusCodes přiřazení jsou výchozí hodnoty používané middlewarem. Změňte hodnoty stavového kódu tak, aby splňovaly vaše požadavky:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
}
});
Potlačení hlaviček mezipaměti
AllowCachingResponses určuje, zda middleware kontroly stavu přidává hlavičky HTTP do odpovědi sondy, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je false
hodnota (výchozí), middleware nastaví nebo přepíše Cache-Control
Expires
, a Pragma
hlavičky, aby se zabránilo ukládání odpovědí do mezipaměti. Pokud je true
hodnota, middleware nezmění hlavičky mezipaměti odpovědi:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
AllowCachingResponses = true
});
Přizpůsobení výstupu
Pokud chcete přizpůsobit výstup sestavy kontrol stavu, nastavte HealthCheckOptions.ResponseWriter vlastnost na delegáta, který zapisuje odpověď:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
ResponseWriter = WriteResponse
});
Výchozí delegát zapíše minimální odpověď prostého textu s řetězcovou hodnotou HealthReport.Status
. Následující vlastní delegát vypíše vlastní 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.
Sonda databáze
Kontrola stavu může zadat databázový dotaz, který se má spustit jako logický test, který indikuje, jestli databáze normálně reaguje.
AspNetCore.Diagnostics.HealthChecks
– knihovna kontroly stavu pro aplikace ASP.NET Core obsahuje kontrolu stavu, která se spouští v databázi SQL Serveru. AspNetCore.Diagnostics.HealthChecks
SELECT 1
spustí dotaz na databázi, aby potvrdil, že připojení k databázi je v pořádku.
Upozorňující
Při kontrole připojení k databázi s dotazem zvolte dotaz, který se rychle vrátí. Přístup k dotazům riskuje přetížení databáze a snížení výkonu. Ve většině případů není spuštění testovacího dotazu nutné. Stačí pouze úspěšné připojení k databázi. Pokud zjistíte, že je nutné spustit dotaz, zvolte jednoduchý dotaz SELECT, například SELECT 1
.
Pokud chcete použít tuto kontrolu stavu SQL Serveru, uveďte odkaz na AspNetCore.HealthChecks.SqlServer
balíček NuGet. Následující příklad zaregistruje kontrolu stavu SQL Serveru:
builder.Services.AddHealthChecks()
.AddSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection"));
Poznámka:
AspNetCore.Diagnostics.HealthChecks
není udržována ani podporována společností Microsoft.
Sonda Entity Framework Core DbContext
Kontrola DbContext
potvrzuje, že aplikace může komunikovat s databází nakonfigurovanou pro aplikaci EF CoreDbContext
. Kontrola je podporovaná DbContext
v aplikacích, které:
- Použijte Entity Framework (EF) Core.
- Zahrňte odkaz na
Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
balíček NuGet.
AddDbContextCheckzaregistruje kontrolu stavu pro DbContext Metoda DbContext
je zadána jako TContext
. K dispozici je přetížení ke konfiguraci stavu selhání, značek a vlastního testovacího dotazu.
Standardně:
- EF Core
CanConnectAsync
VoláníDbContextHealthCheck
metody. Můžete přizpůsobit, jakou operaci se spustí při kontrole stavu pomocíAddDbContextCheck
přetížení metod. - Název kontroly stavu je název
TContext
typu.
Následující příklad zaregistruje a DbContext
přidružené DbContextHealthCheck
:
builder.Services.AddDbContext<SampleDbContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddHealthChecks()
.AddDbContextCheck<SampleDbContext>();
Samostatné testy připravenosti a aktivity
V některých scénářích hostování se k rozlišení dvou stavů aplikace používá pár kontrol stavu:
- Připravenost označuje, jestli aplikace běží normálně, ale není připravená přijímat žádosti.
- Liveness označuje, jestli se aplikace chybově ukončila a musí se restartovat.
Představte si následující příklad: Aplikace musí stáhnout velký konfigurační soubor, než bude připraven zpracovávat požadavky. Nechceme, aby se aplikace restartovala, pokud se počáteční stahování nezdaří, protože aplikace může několikrát zkusit stáhnout soubor znovu. K popisu aktivity procesu používáme sondu živé aktivity, nespustíme žádné další kontroly. Chceme také zabránit tomu, aby se žádosti odesílaly do aplikace před úspěšným stažením konfiguračního souboru. Sondu připravenosti použijeme k označení stavu "nepřipraveno", dokud stahování nebude úspěšné a aplikace bude připravená přijímat žádosti.
Následující úloha na pozadí simuluje proces spuštění, který trvá přibližně 15 sekund. Po dokončení nastaví úloha StartupHealthCheck.StartupCompleted
vlastnost na true:
public class StartupBackgroundService : BackgroundService
{
private readonly StartupHealthCheck _healthCheck;
public StartupBackgroundService(StartupHealthCheck healthCheck)
=> _healthCheck = healthCheck;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// Simulate the effect of a long-running task.
await Task.Delay(TimeSpan.FromSeconds(15), stoppingToken);
_healthCheck.StartupCompleted = true;
}
}
StartupHealthCheck
Hlásí dokončení dlouhotrvající spouštěcí úlohy a zveřejňuje StartupCompleted
vlastnost, která se nastaví službou na pozadí:
public class StartupHealthCheck : IHealthCheck
{
private volatile bool _isReady;
public bool StartupCompleted
{
get => _isReady;
set => _isReady = value;
}
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context, CancellationToken cancellationToken = default)
{
if (StartupCompleted)
{
return Task.FromResult(HealthCheckResult.Healthy("The startup task has completed."));
}
return Task.FromResult(HealthCheckResult.Unhealthy("That startup task is still running."));
}
}
Kontrola stavu je zaregistrovaná AddCheck Program.cs
společně s hostovanými službami. Vzhledem k tomu, že hostovaná služba musí nastavit vlastnost kontroly stavu, je kontrola stavu také zaregistrována v kontejneru služby jako singleton:
builder.Services.AddHostedService<StartupBackgroundService>();
builder.Services.AddSingleton<StartupHealthCheck>();
builder.Services.AddHealthChecks()
.AddCheck<StartupHealthCheck>(
"Startup",
tags: new[] { "ready" });
Pokud chcete vytvořit dva různé koncové body kontroly stavu, volejte MapHealthChecks
dvakrát:
app.MapHealthChecks("/healthz/ready", new HealthCheckOptions
{
Predicate = healthCheck => healthCheck.Tags.Contains("ready")
});
app.MapHealthChecks("/healthz/live", new HealthCheckOptions
{
Predicate = _ => false
});
Předchozí příklad vytvoří následující koncové body kontroly stavu:
/healthz/ready
pro kontrolu připravenosti. Kontrola připravenosti filtruje kontroly stavu na ty, které jsou označenéready
./healthz/live
pro kontrolu živého života. Kontrola aktivity filtruje všechny kontroly stavu vrácenímfalse
delegáta HealthCheckOptions.Predicate . Další informace o filtrování kontrol stavu najdete v tématu Filtrování kontrol stavu v tomto článku.
Před dokončením /healthz/ready
spouštěcí úlohy koncový bod hlásí Unhealthy
stav. Po dokončení spouštěcí úlohy tento koncový bod hlásí Healthy
stav. Koncový /healthz/live
bod vyloučí všechny kontroly a hlásí Healthy
stav všech volání.
Příklad Kubernetes
Použití samostatných kontrol připravenosti a aktivity je užitečné v prostředí, jako je Kubernetes. V Kubernetes může být aplikace nutná ke spouštění časově náročných spouštěcích prací před přijetím požadavků, jako je například test dostupnosti podkladové databáze. Použití samostatných kontrol umožňuje orchestrátoru rozlišit, jestli aplikace funguje, ale ještě není připravená nebo jestli se aplikaci nepodařilo spustit. Další informace o testech připravenosti a aktivity v Kubernetes najdete v dokumentaci ke konfiguraci testů živé aktivity a připravenosti v Kubernetes.
Následující příklad ukazuje konfiguraci sondy připravenosti Kubernetes:
spec:
template:
spec:
readinessProbe:
# an http probe
httpGet:
path: /healthz/ready
port: 80
# length of time to wait for a pod to initialize
# after pod startup, before applying health checking
initialDelaySeconds: 30
timeoutSeconds: 1
ports:
- containerPort: 80
Distribuce knihovny kontroly stavu
Distribuce kontroly stavu jako knihovny:
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.
Napište metodu rozšíření s parametry, které spotřebová aplikace volá ve své
Program.cs
metodě. Podívejte se na následující příklad kontroly stavu, která přijímáarg1
parametry konstruktoru aarg2
jako parametry:public SampleHealthCheckWithArgs(int arg1, string arg2) => (_arg1, _arg2) = (arg1, arg2);
Předchozí podpis označuje, že kontrola stavu vyžaduje vlastní data ke zpracování logiky sondy kontroly stavu. Data se poskytují delegátu použitému k vytvoření instance kontroly stavu při registraci kontroly stavu v metodě rozšíření. V následujícím příkladu volající určuje:
arg1
: Celočíselná datová hodnota pro kontrolu stavu.arg2
: Řetězcový argument pro kontrolu stavu.name
: Volitelný název kontroly stavu. Pokudnull
se použije výchozí hodnota.failureStatus
: Nepovinný údaj HealthStatus, který je hlášen pro stav selhání. Pokudnull
se použije , HealthStatus.Unhealthy použije se.tags
: VolitelnáIEnumerable<string>
kolekce značek.
public static class SampleHealthCheckBuilderExtensions { private const string DefaultName = "Sample"; public static IHealthChecksBuilder AddSampleHealthCheck( this IHealthChecksBuilder healthChecksBuilder, int arg1, string arg2, string? name = null, HealthStatus? failureStatus = null, IEnumerable<string>? tags = default) { return healthChecksBuilder.Add( new HealthCheckRegistration( name ?? DefaultName, _ => new SampleHealthCheckWithArgs(arg1, arg2), failureStatus, tags)); } }
Kontrola stavu – Vydavatel
IHealthCheckPublisher Po přidání do kontejneru služby systém kontroly stavu pravidelně provádí kontroly stavu a volání PublishAsync s výsledkem. Tento proces je užitečný ve scénáři systému monitorování stavu založeného na nabízených oznámeních, který očekává, že každý proces bude pravidelně volat monitorovací systém, aby zjistil stav.
HealthCheckPublisherOptions umožňuje nastavit:
- Delay: Počáteční prodleva použitá po spuštění aplikace před spuštěním IHealthCheckPublisher instancí. Zpoždění se použije jednou při spuštění a nevztahuje se na pozdější iterace. Výchozí hodnota je pět sekund.
- Period: Období IHealthCheckPublisher provádění. Výchozí hodnota je 30 sekund.
- Predicate: Pokud Predicate je
null
(výchozí), spustí služba vydavatele kontroly stavu všechny registrované kontroly stavu. Pokud chcete spustit podmnožinu kontrol stavu, zadejte funkci, která filtruje sadu kontrol. Predikát se vyhodnocuje každé období. - Timeout: Časový limit pro provádění kontrol stavu pro všechny IHealthCheckPublisher instance. Slouží InfiniteTimeSpan ke spuštění bez časového limitu. Výchozí hodnota je 30 sekund.
Následující příklad ukazuje rozložení vydavatele stavu:
public class SampleHealthCheckPublisher : IHealthCheckPublisher
{
public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
{
if (report.Status == HealthStatus.Healthy)
{
// ...
}
else
{
// ...
}
return Task.CompletedTask;
}
}
Třída HealthCheckPublisherOptions poskytuje vlastnosti pro konfiguraci chování vydavatele kontroly stavu.
Následující příklad zaregistruje vydavatele kontroly stavu jako singleton a nakonfiguruje HealthCheckPublisherOptions:
builder.Services.Configure<HealthCheckPublisherOptions>(options =>
{
options.Delay = TimeSpan.FromSeconds(2);
options.Predicate = healthCheck => healthCheck.Tags.Contains("sample");
});
builder.Services.AddSingleton<IHealthCheckPublisher, SampleHealthCheckPublisher>();
Poznámka:
AspNetCore.Diagnostics.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í injektáže závislostí není běžným scénářem konfigurace kontrol stavu. Každá kontrola stavu je obvykle zcela specifická pro skutečný test a je nakonfigurovaná pomocí IHealthChecksBuilder
rozšiřujících metod.
Následující příklad ukazuje ukázkovou kontrolu stavu, která načte objekt konfigurace prostřednictvím injektáže závislostí:
public class SampleHealthCheckWithDI : IHealthCheck
{
private readonly SampleHealthCheckWithDiConfig _config;
public SampleHealthCheckWithDI(SampleHealthCheckWithDiConfig config)
=> _config = config;
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context, CancellationToken cancellationToken = default)
{
var isHealthy = true;
// use _config ...
if (isHealthy)
{
return Task.FromResult(
HealthCheckResult.Healthy("A healthy result."));
}
return Task.FromResult(
new HealthCheckResult(
context.Registration.FailureStatus, "An unhealthy result."));
}
}
Do SampleHealthCheckWithDiConfig
kontejneru služby je potřeba přidat kontrolu stavu:
builder.Services.AddSingleton<SampleHealthCheckWithDiConfig>(new SampleHealthCheckWithDiConfig
{
BaseUriToCheck = new Uri("https://sample.contoso.com/api/")
});
builder.Services.AddHealthChecks()
.AddCheck<SampleHealthCheckWithDI>(
"With Dependency Injection",
tags: new[] { "inject" });
UseHealthChecks vs. MapHealthChecks
Existují dva způsoby zpřístupnění kontrol stavu volajícím:
- UseHealthChecks zaregistruje middleware pro zpracování žádostí o kontroly stavu v kanálu middlewaru.
- MapHealthChecks zaregistruje koncový bod kontroly stavu. Koncový bod se porovná a spustí spolu s dalšími koncovými body v aplikaci.
Výhodou použití MapHealthChecks
oproti UseHealthChecks
tomu je možnost používat middleware s podporou koncových bodů, jako je autorizace, a mít větší jemně odstupňovanou kontrolu nad odpovídajícími zásadami. Hlavní výhodou použití UseHealthChecks
je MapHealthChecks
řízení přesně toho, kde se kontroly stavu spouští v kanálu middlewaru.
- Ukončí kanál, když požadavek odpovídá koncovému bodu kontroly stavu. Zkratování je často žádoucí, protože zabraňuje zbytečné práci, jako je protokolování a další middleware.
- Primárně se používá ke konfiguraci middlewaru kontroly stavu v kanálu.
- Může odpovídat jakékoli cestě na portu s nebo prázdným
null
PathString
. Umožňuje provést kontrolu stavu u všech požadavků provedených na zadaném portu. - Zdrojový kód
MapHealthChecks umožňuje:
- Mapování konkrétních tras nebo koncových bodů pro kontroly stavu
- Přizpůsobení adresy URL nebo cesty, kde je koncový bod kontroly stavu přístupný.
- Mapování několika koncových bodů kontroly stavu s různými trasami nebo konfiguracemi Podpora více koncových bodů:
- Umožňuje samostatné koncové body pro různé typy kontrol stavu nebo součástí.
- Používá se k rozlišení různých aspektů stavu aplikace nebo použití konkrétních konfigurací na podmnožinu kontrol stavu.
- Zdrojový kód
Další materiály
Poznámka:
Tento článek byl částečně vytvořen pomocí umělé inteligence. Před zveřejněním autor obsah zkontroloval a podle potřeby upravil. Viz Naše zásady pro používání obsahu generovaného AI v Microsoft Learn.