Udostępnij za pośrednictwem


Kontrole kondycji w programie ASP.NET Core

Przez Glenn Condron i Juergen Gutsch

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ostrzeżenie

Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz .NET i .NET Core Support Policy (Zasady obsługi platformy .NET Core). Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

ASP.NET Core oferuje oprogramowanie pośredniczące kontroli kondycji i biblioteki do raportowania kondycji składników infrastruktury aplikacji.

Testy kondycji są udostępniane przez aplikację jako punkty końcowe HTTP. Punkty końcowe kontroli kondycji można skonfigurować dla różnych scenariuszy monitorowania w czasie rzeczywistym:

  • Sondy kondycji mogą być używane przez koordynatorów kontenerów i moduły równoważenia obciążenia w celu sprawdzenia stanu aplikacji. Na przykład orkiestrator kontenerów może reagować na niepowodzenie sprawdzania kondycji, zatrzymując wdrożenie stopniowe lub ponownie uruchamiając kontener. Moduł równoważenia obciążenia może reagować na aplikację w złej kondycji, rozsyłając ruch z dala od wystąpienia w dobrej kondycji.
  • Użycie pamięci, dysku i innych zasobów serwera fizycznego można monitorować pod kątem stanu dobrej kondycji.
  • Testy kondycji mogą testować zależności aplikacji, takie jak bazy danych i zewnętrzne punkty końcowe usługi, w celu potwierdzenia dostępności i normalnego działania.

Testy kondycji są zwykle używane z zewnętrzną usługą monitorowania lub koordynatorem kontenerów w celu sprawdzenia stanu aplikacji. Przed dodaniem kontroli kondycji do aplikacji zdecyduj, który system monitorowania ma być używany. System monitorowania określa typy kontroli kondycji do utworzenia i sposobu konfigurowania ich punktów końcowych.

Podstawowa sonda kondycji

W przypadku wielu aplikacji podstawowa konfiguracja sondy kondycji, która zgłasza dostępność aplikacji do przetwarzania żądań (żywości) jest wystarczająca do odnalezienia stanu aplikacji.

Podstawowa konfiguracja rejestruje usługi sprawdzania kondycji i wywołuje oprogramowanie pośredniczące kontroli kondycji, aby odpowiedzieć w punkcie końcowym adresu URL z odpowiedzią na kondycję. Domyślnie żadne konkretne kontrole kondycji nie są rejestrowane w celu przetestowania żadnej konkretnej zależności lub podsystemu. Aplikacja jest uważana za w dobrej kondycji, jeśli może odpowiadać pod adresem URL punktu końcowego kondycji. Domyślny składnik zapisywania odpowiedzi zapisuje HealthStatus jako odpowiedź w postaci zwykłego tekstu na klienta. Parametr HealthStatus to HealthStatus.Healthy, HealthStatus.Degradedlub HealthStatus.Unhealthy.

Zarejestruj usługi sprawdzania kondycji za pomocą AddHealthChecks polecenia w programie Program.cs. Utwórz punkt końcowy kontroli kondycji, wywołując polecenie MapHealthChecks.

Poniższy przykład tworzy punkt końcowy kontroli kondycji w witrynie /healthz:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHealthChecks();

var app = builder.Build();

app.MapHealthChecks("/healthz");

app.Run();

Docker HEALTHCHECK

Platforma Docker oferuje wbudowaną HEALTHCHECK dyrektywę, która może służyć do sprawdzania stanu aplikacji korzystającej z podstawowej konfiguracji kontroli kondycji:

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

W poprzednim przykładzie użyto curl metody , aby wysłać żądanie HTTP do punktu końcowego sprawdzania kondycji pod adresem /healthz. curl nie jest uwzględniana w obrazach kontenerów systemu Linux platformy .NET, ale można ją dodać, instalując wymagany pakiet w pliku Dockerfile. Kontenery korzystające z obrazów opartych na systemie Alpine Linux mogą używać elementów dołączonych wget curlzamiast programu .

Tworzenie kontroli kondycji

Testy kondycji są tworzone przez zaimplementowanie interfejsu IHealthCheck . Metoda CheckHealthAsync zwraca wartość HealthCheckResult , która wskazuje kondycję jako Healthy, Degradedlub Unhealthy. Wynik jest zapisywany jako odpowiedź w postaci zwykłego tekstu z konfigurowalnym kodem stanu. Konfiguracja została opisana w sekcji Opcje sprawdzania kondycji. HealthCheckResult może również zwracać opcjonalne pary klucz-wartość.

W poniższym przykładzie pokazano układ kontroli kondycji:

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 kontroli kondycji jest umieszczana w metodzie CheckHealthAsync . W poprzednim przykładzie ustawiono fikcyjną zmienną , isHealthyna truewartość . Jeśli wartość parametru isHealthy jest ustawiona na falsewartość , HealthCheckRegistration.FailureStatus zwracany jest stan.

Jeśli CheckHealthAsync podczas sprawdzania zostanie zgłoszony wyjątek, zostanie zwrócony nowy HealthReportEntry element z ustawioną HealthReportEntry.Status wartością FailureStatus. Ten stan jest definiowany przez AddCheck (zobacz sekcję Rejestrowanie usług sprawdzania kondycji) i zawiera wyjątek wewnętrzny, który spowodował niepowodzenie sprawdzania. Parametr Description jest ustawiony na komunikat wyjątku.

Rejestrowanie usług kontroli kondycji

Aby zarejestrować usługę sprawdzania kondycji, wywołaj metodę w pliku AddCheck Program.cs:

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

Przeciążenie AddCheck pokazane w poniższym przykładzie ustawia stan błędu (HealthStatus) w celu raportowania, gdy kontrola kondycji zgłasza błąd. Jeśli stan niepowodzenia jest ustawiony na null (wartość domyślna), HealthStatus.Unhealthy jest zgłaszany. To przeciążenie jest przydatnym scenariuszem dla autorów bibliotek, w którym stan awarii wskazywany przez bibliotekę jest wymuszany przez aplikację, gdy wystąpi błąd sprawdzania kondycji, jeśli implementacja kontroli kondycji honoruje ustawienie.

Tagi mogą służyć do filtrowania kontroli kondycji. Tagi są opisane w sekcji Filtrowanie kontroli kondycji.

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

AddCheck może również wykonać funkcję lambda. W poniższym przykładzie sprawdzanie kondycji zawsze zwraca wynik w dobrej kondycji:

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

Wywołaj metodę AddTypeActivatedCheck , aby przekazać argumenty do implementacji kontroli kondycji. W poniższym przykładzie kontrola kondycji aktywowana typem akceptuje liczbę całkowitą i ciąg w konstruktorze:

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

Aby zarejestrować poprzednią kontrolę kondycji, wywołaj metodę AddTypeActivatedCheck za pomocą liczby całkowitej i ciągu przekazanego jako argumenty:

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

Używanie routingu sprawdzania kondycji

W Program.cspliku wywołaj MapHealthChecks konstruktora punktu końcowego przy użyciu adresu URL punktu końcowego lub ścieżki względnej:

app.MapHealthChecks("/healthz");

Wymagaj hosta

Wywołaj metodę RequireHost , aby określić co najmniej jeden dozwolony host dla punktu końcowego kontroli kondycji. Hosty powinny być unicode, a nie punycode i mogą zawierać port. Jeśli kolekcja nie zostanie dostarczona, zostanie zaakceptowany żaden host:

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

Aby ograniczyć punkt końcowy kontroli kondycji do odpowiadania tylko na określonym porcie, określ port w wywołaniu metody RequireHost. Takie podejście jest zwykle używane w środowisku kontenera do uwidaczniania portu na potrzeby usług monitorowania:

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

Ostrzeżenie

Interfejs API, który opiera się na nagłówku hosta, takim jak HttpRequest.Host i RequireHost, podlega potencjalnemu fałszowaniu przez klientów.

Aby zapobiec fałszowaniu hostów i portów, użyj jednej z następujących metod:

Aby zapobiec fałszowaniu portu przez nieautoryzowanych klientów, wywołaj metodę RequireAuthorization:

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

Aby uzyskać więcej informacji, zobacz Dopasowywanie hostów w trasach za pomocą elementu RequireHost.

Wymagaj autoryzacji

Wywołaj polecenie RequireAuthorization , aby uruchomić oprogramowanie pośredniczące autoryzacji w punkcie końcowym żądania sprawdzania kondycji. Przeciążenie RequireAuthorization akceptuje co najmniej jedną zasady autoryzacji. Jeśli nie podano zasad, są używane domyślne zasady autoryzacji:

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

Włączanie żądań Cross-Origin (CORS)

Mimo że ręczne uruchamianie kontroli kondycji z przeglądarki nie jest typowym scenariuszem, oprogramowanie pośredniczące CORS można włączyć przez wywołanie RequireCors punktów końcowych kontroli kondycji. Przeciążenie RequireCors akceptuje delegata konstruktora zasad CORS (CorsPolicyBuilder) lub nazwę zasad. Aby uzyskać więcej informacji, zobacz Włączanie żądań między źródłami (CORS) w ASP.NET Core.

Opcje kontroli kondycji

HealthCheckOptions umożliwia dostosowanie zachowania kontroli kondycji:

Filtrowanie kontroli kondycji

Domyślnie oprogramowanie pośredniczące sprawdzania kondycji uruchamia wszystkie zarejestrowane kontrole kondycji. Aby uruchomić podzbiór kontroli kondycji, podaj funkcję, która zwraca wartość logiczną do Predicate opcji.

Poniższy przykład filtruje testy kondycji tak, aby tylko te oznaczone przebiegiem sample :

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

Dostosowywanie kodu stanu HTTP

Służy ResultStatusCodes do dostosowywania mapowania stanu kondycji na kody stanu HTTP. Następujące StatusCodes przypisania są wartościami domyślnymi używanymi przez oprogramowanie pośredniczące. Zmień wartości kodu stanu, aby spełnić wymagania:

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

Pomijanie nagłówków pamięci podręcznej

AllowCachingResponses określa, czy oprogramowanie pośredniczące kontroli kondycji dodaje nagłówki HTTP do odpowiedzi sondy, aby zapobiec buforowaniu odpowiedzi. Jeśli wartość to false (wartość domyślna), oprogramowanie pośredniczące ustawia lub zastępuje Cache-Controlnagłówki , Expiresi Pragma , aby zapobiec buforowaniu odpowiedzi. Jeśli wartość to true, oprogramowanie pośredniczące nie modyfikuje nagłówków pamięci podręcznej odpowiedzi:

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

Dostosowywanie danych wyjściowych

Aby dostosować dane wyjściowe raportu kontroli kondycji, ustaw HealthCheckOptions.ResponseWriter właściwość na delegata, który zapisuje odpowiedź:

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

Domyślny delegat zapisuje minimalną odpowiedź w postaci zwykłego tekstu z wartością HealthReport.Statusciągu . Poniższy delegat niestandardowy zwraca niestandardową odpowiedź JSON przy użyciu polecenia 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()));
}

Interfejs API sprawdzania kondycji nie zapewnia wbudowanej obsługi złożonych formatów zwracanych JSON, ponieważ format jest specyficzny dla wybranego systemu monitorowania. Dostosuj odpowiedź w poprzednich przykładach zgodnie z potrzebami. Aby uzyskać więcej informacji na temat serializacji JSON za pomocą System.Text.Jsonprogramu , zobacz Jak serializować i deserializować kod JSON na platformie .NET.

Sonda bazy danych

Kontrola kondycji może określić zapytanie bazy danych do uruchomienia jako test logiczny, aby wskazać, czy baza danych odpowiada normalnie.

AspNetCore.Diagnostics.HealthChecks, biblioteka sprawdzania kondycji dla aplikacji ASP.NET Core zawiera kontrolę kondycji uruchamianą względem bazy danych programu SQL Server. AspNetCore.Diagnostics.HealthChecksSELECT 1 Wykonuje zapytanie względem bazy danych, aby potwierdzić, że połączenie z bazą danych jest w dobrej kondycji.

Ostrzeżenie

Podczas sprawdzania połączenia bazy danych z zapytaniem wybierz zapytanie, które szybko zwraca. Podejście do zapytania powoduje przeciążenie bazy danych i obniżenie wydajności. W większości przypadków uruchomienie zapytania testowego nie jest konieczne. Wystarczy nawiązać pomyślne połączenie z bazą danych. Jeśli okaże się, że konieczne jest uruchomienie zapytania, wybierz proste zapytanie SELECT, takie jak SELECT 1.

Aby użyć tej kontroli kondycji programu SQL Server, dołącz odwołanie do AspNetCore.HealthChecks.SqlServer pakietu NuGet. Poniższy przykład rejestruje kontrolę kondycji programu SQL Server:

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

Uwaga

AspNetCore.Diagnostics.HealthChecks firma Microsoft nie jest obsługiwana ani obsługiwana.

Sonda DbContext platformy Entity Framework Core

Sprawdzanie DbContext potwierdza, że aplikacja może komunikować się z bazą danych skonfigurowaną dla elementu EF CoreDbContext. Sprawdzanie DbContext jest obsługiwane w aplikacjach, które:

AddDbContextCheck rejestruje kontrolę kondycji dla elementu DbContext. Element DbContext jest dostarczany do metody jako TContext. Przeciążenie jest dostępne do skonfigurowania stanu niepowodzenia, tagów i niestandardowego zapytania testowego.

Domyślnie:

  • Wywołania DbContextHealthCheck EF CoreCanConnectAsync metody . Możesz dostosować operację uruchamianą podczas sprawdzania kondycji przy użyciu AddDbContextCheck przeciążeń metod.
  • Nazwa sprawdzania kondycji to nazwa TContext typu.

Poniższy przykład rejestruje element DbContext i skojarzony element DbContextHealthCheck:

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

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

Oddzielne sondy gotowości i aktualności

W niektórych scenariuszach hostingu para kontroli kondycji służy do rozróżniania dwóch stanów aplikacji:

  • Gotowość wskazuje, czy aplikacja działa normalnie, ale nie jest gotowa do odbierania żądań.
  • Liveness wskazuje, czy aplikacja uległa awarii i musi zostać ponownie uruchomiona.

Rozważmy następujący przykład: Aplikacja musi pobrać duży plik konfiguracji, zanim będzie gotowa do przetwarzania żądań. Nie chcemy, aby aplikacja została ponownie uruchomiona, jeśli początkowe pobieranie nie powiedzie się, ponieważ aplikacja może ponowić próbę pobrania pliku kilka razy. Używamy sondy liveness do opisania aktualności procesu, nie są uruchamiane żadne inne testy. Chcemy również uniemożliwić wysyłanie żądań do aplikacji przed pomyślnym pobraniem pliku konfiguracji. Używamy sondy gotowości, aby wskazać stan "nie jest gotowy", dopóki pobieranie nie powiedzie się, a aplikacja będzie gotowa do odbierania żądań.

Następujące zadanie w tle symuluje proces uruchamiania, który trwa około 15 sekund. Po zakończeniu zadania zadanie ustawia StartupHealthCheck.StartupCompleted właściwość 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;
    }
}

Raportuje StartupHealthCheck ukończenie długotrwałego zadania uruchamiania i uwidacznia StartupCompleted właściwość ustawianą przez usługę w tle:

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 kondycji jest zarejestrowana AddCheck razem Program.cs z hostowaną usługą. Ponieważ hostowana usługa musi ustawić właściwość w kontroli kondycji, sprawdzanie kondycji jest również zarejestrowane w kontenerze usługi jako pojedynczy:

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

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

Aby utworzyć dwa różne punkty końcowe kontroli kondycji, wywołaj dwa MapHealthChecks razy:

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

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

W poprzednim przykładzie są tworzone następujące punkty końcowe sprawdzania kondycji:

  • /healthz/ready w celu sprawdzenia gotowości. Sprawdzanie gotowości filtruje kontrole kondycji do tych oznaczonych tagiem ready.
  • /healthz/live w celu sprawdzenia aktualności. Sprawdzanie aktualności filtruje wszystkie kontrole kondycji, wracając false do delegata HealthCheckOptions.Predicate . Aby uzyskać więcej informacji na temat filtrowania kontroli kondycji, zobacz Filtrowanie kontroli kondycji w tym artykule.

Przed ukończeniem zadania uruchamiania /healthz/ready punkt końcowy zgłasza Unhealthy stan. Po zakończeniu zadania uruchamiania ten punkt końcowy zgłasza Healthy stan. Punkt /healthz/live końcowy wyklucza wszystkie kontrole i zgłasza Healthy stan wszystkich wywołań.

Przykład rozwiązania Kubernetes

Korzystanie z oddzielnych testów gotowości i dostępności jest przydatne w środowisku, takim jak Kubernetes. Na platformie Kubernetes aplikacja może być wymagana do wykonywania czasochłonnej pracy podczas uruchamiania przed zaakceptowaniem żądań, takich jak test dostępności bazowej bazy danych. Użycie oddzielnych kontroli umożliwia orkiestratorowi rozróżnienie, czy aplikacja działa, ale nie jest jeszcze gotowa, czy nie można uruchomić aplikacji. Aby uzyskać więcej informacji na temat sond gotowości i aktualności na platformie Kubernetes, zobacz Konfigurowanie sondy kondycji i gotowości w dokumentacji platformy Kubernetes.

W poniższym przykładzie pokazano konfigurację sondy gotowości platformy 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

Rozpowszechnianie biblioteki kontroli kondycji

Aby rozpowszechnić kontrolę kondycji jako bibliotekę:

  1. Napisz kontrolę kondycji, która implementuje IHealthCheck interfejs jako klasę autonomiczną. Klasa może polegać na iniekcji zależności (DI), aktywacji typu i nazwanych opcjach uzyskiwania dostępu do danych konfiguracji.

  2. Napisz metodę rozszerzenia z parametrami, które aplikacja zużywającą wywołuje w swojej Program.cs metodzie. Rozważmy następujący przykładowy sprawdzanie kondycji, który akceptuje arg1 parametry konstruktora i arg2 jako parametry konstruktora:

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

    Powyższy podpis wskazuje, że kontrola kondycji wymaga niestandardowych danych do przetwarzania logiki sondy sprawdzania kondycji. Dane są udostępniane delegatowi użytemu do utworzenia wystąpienia kontroli kondycji po zarejestrowaniu sprawdzania kondycji za pomocą metody rozszerzenia. W poniższym przykładzie obiekt wywołujący określa:

    • arg1: punkt danych liczby całkowitej dla sprawdzania kondycji.
    • arg2: argument ciągu dla sprawdzania kondycji.
    • name: opcjonalna nazwa sprawdzania kondycji. Jeśli nullzostanie użyta wartość domyślna.
    • failureStatus: opcjonalny HealthStatuselement , który jest zgłaszany dla stanu błędu. HealthStatus.Unhealthy Jeśli nullparametr jest używany.
    • tags: opcjonalna IEnumerable<string> kolekcja tagów.
    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));
        }
    }
    

Wydawca kontroli kondycji

Po dodaniu elementu IHealthCheckPublisher do kontenera usługi system sprawdzania kondycji okresowo wykonuje testy kondycji i wywołuje PublishAsync wynik. Ten proces jest przydatny w scenariuszu systemu monitorowania kondycji opartego na wypychaniach, który oczekuje, że każdy proces będzie okresowo wywoływać system monitorowania w celu określenia kondycji.

HealthCheckPublisherOptions umożliwia ustawienie następujących opcji:

  • Delay: początkowe opóźnienie zastosowane po uruchomieniu aplikacji przed wykonaniem IHealthCheckPublisher wystąpień. Opóźnienie jest stosowane raz podczas uruchamiania i nie ma zastosowania do późniejszych iteracji. Wartość domyślna to pięć sekund.
  • Period: okres IHealthCheckPublisher wykonywania. Wartość domyślna to 30 sekund.
  • Predicate: Jeśli Predicate jest null (wartość domyślna), usługa wydawcy sprawdzania kondycji uruchamia wszystkie zarejestrowane testy kondycji. Aby uruchomić podzbiór kontroli kondycji, podaj funkcję, która filtruje zestaw testów. Predykat jest obliczany w każdym okresie.
  • Timeout: limit czasu wykonywania kontroli kondycji dla wszystkich IHealthCheckPublisher wystąpień. Użyj polecenia InfiniteTimeSpan , aby wykonać bez limitu czasu. Wartość domyślna to 30 sekund.

W poniższym przykładzie pokazano układ wydawcy kondycji:

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

        return Task.CompletedTask;
    }
}

Klasa HealthCheckPublisherOptions udostępnia właściwości służące do konfigurowania zachowania wydawcy kontroli kondycji.

W poniższym przykładzie wydawca kontroli kondycji jest rejestrowany jako pojedynczy użytkownik i konfiguruje HealthCheckPublisherOptionselement :

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:

  • Zawiera wydawców dla kilku systemów, w tym usługi Application Insights.
  • Firma Microsoft nie jest obsługiwana ani nie jest obsługiwana.

Indywidualne kontrole kondycji

Delay i Period można ustawić dla każdego z nich HealthCheckRegistration indywidualnie. Jest to przydatne, gdy chcesz uruchomić kilka kontroli kondycji z inną szybkością niż okres ustawiony w .HealthCheckPublisherOptions

Poniższy kod ustawia wartości Delay i Period dla elementu 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();

Wstrzykiwanie zależności i kontrole kondycji

Można użyć iniekcji zależności, aby użyć wystąpienia określonego Type wewnątrz klasy Kontroli kondycji. Wstrzykiwanie zależności może być przydatne do wstrzykiwania opcji lub konfiguracji globalnej do kontroli kondycji. Używanie wstrzykiwania zależności nie jest typowym scenariuszem konfigurowania kontroli kondycji. Zwykle każda kontrola kondycji jest dość specyficzna dla rzeczywistego testu i jest konfigurowana przy użyciu IHealthChecksBuilder metod rozszerzeń.

W poniższym przykładzie pokazano przykładową kontrolę kondycji, która pobiera obiekt konfiguracji za pośrednictwem iniekcji zależności:

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

Element SampleHealthCheckWithDiConfig i sprawdzanie kondycji należy dodać do kontenera usługi :

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

Istnieją dwa sposoby udostępniania kontroli kondycji obiektom wywołującym:

  • UseHealthChecks rejestruje oprogramowanie pośredniczące do obsługi żądań kontroli kondycji w potoku oprogramowania pośredniczącego.
  • MapHealthChecks rejestruje punkt końcowy kontroli kondycji. Punkt końcowy jest zgodny i wykonywany wraz z innymi punktami końcowymi w aplikacji.

Zaletą używania MapHealthChecks funkcji over UseHealthChecks jest możliwość używania oprogramowania pośredniczącego obsługującego punkty końcowe, takiego jak autoryzacja, oraz większej precyzyjnej kontroli nad pasującymi zasadami. Główną zaletą używania UseHealthChecks funkcji over MapHealthChecks jest kontrolowanie dokładnie tego, gdzie testy kondycji są uruchamiane w potoku oprogramowania pośredniczącego.

UseHealthChecks:

  • Przerywa potok, gdy żądanie jest zgodne z punktem końcowym sprawdzania kondycji. Zwarcie jest często pożądane, ponieważ pozwala uniknąć niepotrzebnej pracy, takiej jak rejestrowanie i inne oprogramowanie pośredniczące.
  • Służy głównie do konfigurowania oprogramowania pośredniczącego kontroli kondycji w potoku.
  • Może być zgodna z dowolną ścieżką na porcie lub pustą null PathString. Umożliwia przeprowadzenie kontroli kondycji dla dowolnego żądania skierowanego do określonego portu.
  • Kod źródłowy

MapHealthChecks Pozwala:

  • Kończenie potoku, gdy żądanie jest zgodne z punktem końcowym sprawdzania kondycji, wywołując metodę ShortCircuit. Na przykład app.MapHealthChecks("/healthz").ShortCircuit();. Aby uzyskać więcej informacji, zobacz Oprogramowanie pośredniczące zwarcie po routingu.
  • Mapowanie określonych tras lub punktów końcowych na potrzeby kontroli kondycji.
  • Dostosowanie adresu URL lub ścieżki, w której jest dostępny punkt końcowy sprawdzania kondycji.
  • Mapowanie wielu punktów końcowych kontroli kondycji z różnymi trasami lub konfiguracjami. Obsługa wielu punktów końcowych:
    • Włącza oddzielne punkty końcowe dla różnych typów kontroli kondycji lub składników.
    • Służy do rozróżniania różnych aspektów kondycji aplikacji lub stosowania określonych konfiguracji do podzbiorów kontroli kondycji.
  • Kod źródłowy

Dodatkowe zasoby

Uwaga

Ten artykuł został częściowo utworzony z pomocą sztucznej inteligencji. Przed opublikowaniem autor przejrzał i poprawił zawartość zgodnie z potrzebą. Zapoznaj się z naszymi zasadami korzystania z zawartości generowanej za pośrednictwem AI w usłudze Microsoft Learn.

ASP.NET Core oferuje oprogramowanie pośredniczące kontroli kondycji i biblioteki do raportowania kondycji składników infrastruktury aplikacji.

Testy kondycji są udostępniane przez aplikację jako punkty końcowe HTTP. Punkty końcowe kontroli kondycji można skonfigurować dla różnych scenariuszy monitorowania w czasie rzeczywistym:

  • Sondy kondycji mogą być używane przez koordynatorów kontenerów i moduły równoważenia obciążenia w celu sprawdzenia stanu aplikacji. Na przykład orkiestrator kontenerów może reagować na niepowodzenie sprawdzania kondycji, zatrzymując wdrożenie stopniowe lub ponownie uruchamiając kontener. Moduł równoważenia obciążenia może reagować na aplikację w złej kondycji, rozsyłając ruch z dala od wystąpienia w dobrej kondycji.
  • Użycie pamięci, dysku i innych zasobów serwera fizycznego można monitorować pod kątem stanu dobrej kondycji.
  • Testy kondycji mogą testować zależności aplikacji, takie jak bazy danych i zewnętrzne punkty końcowe usługi, w celu potwierdzenia dostępności i normalnego działania.

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Przykładowa aplikacja zawiera przykłady scenariuszy opisanych w tym artykule. Aby uruchomić przykładową aplikację dla danego scenariusza, użyj polecenia dotnet run z folderu projektu w powłoce poleceń. Zobacz plik przykładowej README.md aplikacji i opisy scenariuszy w tym artykule, aby uzyskać szczegółowe informacje na temat korzystania z przykładowej aplikacji.

Wymagania wstępne

Testy kondycji są zwykle używane z zewnętrzną usługą monitorowania lub koordynatorem kontenerów w celu sprawdzenia stanu aplikacji. Przed dodaniem kontroli kondycji do aplikacji zdecyduj, który system monitorowania ma być używany. System monitorowania określa typy kontroli kondycji do utworzenia i sposobu konfigurowania ich punktów końcowych.

Pakiet Microsoft.AspNetCore.Diagnostics.HealthChecks jest przywołyyny niejawnie dla aplikacji ASP.NET Core. Aby uruchomić kontrole kondycji przy użyciu programu Entity Framework Core, dodaj odwołanie do Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore pakietu.

Przykładowa aplikacja udostępnia kod uruchamiania w celu zademonstrowania kontroli kondycji dla kilku scenariuszy. Scenariusz sondy bazy danych sprawdza kondycję połączenia z bazą danych przy użyciu polecenia AspNetCore.Diagnostics.HealthChecks. Scenariusz sondy DbContext sprawdza bazę danych przy użyciu elementu EF CoreDbContext. Aby zapoznać się ze scenariuszami bazy danych, przykładowa aplikacja:

Uwaga

AspNetCore.Diagnostics.HealthChecks firma Microsoft nie jest obsługiwana ani obsługiwana.

Inny scenariusz kontroli kondycji przedstawia sposób filtrowania kontroli kondycji na porcie zarządzania. Przykładowa aplikacja wymaga utworzenia pliku zawierającego Properties/launchSettings.json adres URL zarządzania i port zarządzania. Aby uzyskać więcej informacji, zobacz sekcję Filtruj według portów .

Podstawowa sonda kondycji

W przypadku wielu aplikacji podstawowa konfiguracja sondy kondycji, która zgłasza dostępność aplikacji do przetwarzania żądań (żywości) jest wystarczająca do odnalezienia stanu aplikacji.

Podstawowa konfiguracja rejestruje usługi sprawdzania kondycji i wywołuje oprogramowanie pośredniczące kontroli kondycji, aby odpowiedzieć w punkcie końcowym adresu URL z odpowiedzią na kondycję. Domyślnie żadne konkretne kontrole kondycji nie są rejestrowane w celu przetestowania żadnej konkretnej zależności lub podsystemu. Aplikacja jest uważana za w dobrej kondycji, jeśli może odpowiadać pod adresem URL punktu końcowego kondycji. Domyślny składnik zapisywania odpowiedzi zapisuje stan (HealthStatus) jako odpowiedź w postaci zwykłego tekstu z powrotem do klienta, wskazując stan HealthStatus.Healthy, HealthStatus.Degradedlub HealthStatus.Unhealthy .

Zarejestruj usługi sprawdzania kondycji za pomocą AddHealthChecks polecenia w programie Startup.ConfigureServices. Utwórz punkt końcowy kontroli kondycji, wywołując polecenie MapHealthChecks w pliku Startup.Configure.

W przykładowej aplikacji punkt końcowy sprawdzania kondycji jest tworzony pod adresem /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");
        });
    }
}

Aby uruchomić podstawowy scenariusz konfiguracji przy użyciu przykładowej aplikacji, wykonaj następujące polecenie z folderu projektu w powłoce poleceń:

dotnet run --scenario basic

Przykład platformy Docker

Platforma Docker oferuje wbudowaną HEALTHCHECK dyrektywę, która może służyć do sprawdzania stanu aplikacji korzystającej z podstawowej konfiguracji kontroli kondycji:

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

Tworzenie kontroli kondycji

Testy kondycji są tworzone przez zaimplementowanie interfejsu IHealthCheck . Metoda CheckHealthAsync zwraca wartość HealthCheckResult , która wskazuje kondycję jako Healthy, Degradedlub Unhealthy. Wynik jest zapisywany jako odpowiedź w postaci zwykłego tekstu z konfigurowalnym kodem stanu (konfiguracja jest opisana w sekcji Opcje sprawdzania kondycji). HealthCheckResult może również zwracać opcjonalne pary klucz-wartość.

Poniższa ExampleHealthCheck klasa demonstruje układ kontroli kondycji. Logika kontroli kondycji jest umieszczana w metodzie CheckHealthAsync . W poniższym przykładzie ustawiono fikcyjną zmienną , healthCheckResultHealthyna true. Jeśli wartość parametru healthCheckResultHealthy jest ustawiona na falsewartość , HealthCheckRegistration.FailureStatus zwracany jest stan.

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

Jeśli CheckHealthAsync podczas sprawdzania zostanie zgłoszony wyjątek, zostanie zwrócony nowy HealthReportEntry element z HealthReportEntry.Status ustawionym elementem FailureStatus, który jest zdefiniowany przez AddCheck (zobacz sekcję Usługi sprawdzania kondycji rejestru) i zawiera wyjątek wewnętrzny, który początkowo spowodował błąd sprawdzania. Parametr Description jest ustawiony na komunikat wyjątku.

Rejestrowanie usług kontroli kondycji

Typ jest dodawany do usług sprawdzania ExampleHealthCheck kondycji za pomocą AddCheck polecenia w pliku :Startup.ConfigureServices

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

Przeciążenie AddCheck pokazane w poniższym przykładzie ustawia stan błędu (HealthStatus) w celu raportowania, gdy kontrola kondycji zgłasza błąd. Jeśli stan niepowodzenia jest ustawiony na null (wartość domyślna), HealthStatus.Unhealthy jest zgłaszany. To przeciążenie jest przydatnym scenariuszem dla autorów bibliotek, w którym stan awarii wskazywany przez bibliotekę jest wymuszany przez aplikację, gdy wystąpi błąd sprawdzania kondycji, jeśli implementacja kontroli kondycji honoruje ustawienie.

Tagi mogą służyć do filtrowania kontroli kondycji (opisanych dalej w sekcji Kontrole kondycji filtru).

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

AddCheck może również wykonać funkcję lambda. W poniższym przykładzie nazwa kontroli kondycji jest określona jako Example i sprawdzanie zawsze zwraca stan dobrej kondycji:

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

Wywołaj metodę AddTypeActivatedCheck , aby przekazać argumenty do implementacji kontroli kondycji. W poniższym przykładzie TestHealthCheckWithArgs akceptuje liczbę całkowitą i ciąg do użycia, gdy CheckHealthAsync jest wywoływany:

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 jest rejestrowany przez wywołanie AddTypeActivatedCheck za pomocą liczby całkowitej i ciągu przekazanego do implementacji:

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

Używanie routingu sprawdzania kondycji

W Startup.Configurepliku wywołaj MapHealthChecks konstruktora punktu końcowego przy użyciu adresu URL punktu końcowego lub ścieżki względnej:

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

Wymagaj hosta

Wywołaj metodę RequireHost , aby określić co najmniej jeden dozwolony host dla punktu końcowego kontroli kondycji. Hosty powinny być unicode, a nie punycode i mogą zawierać port. Jeśli kolekcja nie zostanie dostarczona, zostanie zaakceptowany żaden host.

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

Aby uzyskać więcej informacji, zobacz sekcję Filtruj według portów .

Wymagaj autoryzacji

Wywołaj polecenie RequireAuthorization , aby uruchomić oprogramowanie pośredniczące autoryzacji w punkcie końcowym żądania sprawdzania kondycji. Przeciążenie RequireAuthorization akceptuje co najmniej jedną zasady autoryzacji. Jeśli nie podano zasad, są używane domyślne zasady autoryzacji.

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

Włączanie żądań Cross-Origin (CORS)

Mimo że ręczne uruchamianie kontroli kondycji z przeglądarki nie jest typowym scenariuszem użycia, oprogramowanie pośredniczące CORS można włączyć przez wywołanie RequireCors punktów końcowych kontroli kondycji. Przeciążenie RequireCors akceptuje delegata konstruktora zasad CORS (CorsPolicyBuilder) lub nazwę zasad. Jeśli nie podano zasad, zostanie użyta domyślna zasada CORS. Aby uzyskać więcej informacji, zobacz Włączanie żądań między źródłami (CORS) w ASP.NET Core.

Opcje kontroli kondycji

HealthCheckOptions umożliwia dostosowanie zachowania kontroli kondycji:

Filtrowanie kontroli kondycji

Domyślnie oprogramowanie pośredniczące sprawdzania kondycji uruchamia wszystkie zarejestrowane testy kondycji. Aby uruchomić podzbiór kontroli kondycji, podaj funkcję, która zwraca wartość logiczną do Predicate opcji. W poniższym przykładzie Bar sprawdzanie kondycji jest filtrowane według tagu (bar_tag) w instrukcji warunkowej funkcji, gdzie true jest zwracana tylko wtedy, gdy właściwość sprawdzania kondycji Tags jest zgodna foo_tag z właściwością lub baz_tag:

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

W Startup.Configurepliku filtruje Predicate sprawdzanie kondycji paska. Wykonaj tylko polecenia Foo i Baz:

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

Dostosowywanie kodu stanu HTTP

Służy ResultStatusCodes do dostosowywania mapowania stanu kondycji na kody stanu HTTP. Następujące StatusCodes przypisania są wartościami domyślnymi używanymi przez oprogramowanie pośredniczące. Zmień wartości kodu stanu, aby spełniały twoje wymagania.

W pliku Startup.Configure:

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

Pomijanie nagłówków pamięci podręcznej

AllowCachingResponses określa, czy oprogramowanie pośredniczące kontroli kondycji dodaje nagłówki HTTP do odpowiedzi sondy, aby zapobiec buforowaniu odpowiedzi. Jeśli wartość to false (wartość domyślna), oprogramowanie pośredniczące ustawia lub zastępuje Cache-Controlnagłówki , Expiresi Pragma , aby zapobiec buforowaniu odpowiedzi. Jeśli wartość to true, oprogramowanie pośredniczące nie modyfikuje nagłówków pamięci podręcznej odpowiedzi.

W pliku Startup.Configure:

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

Dostosowywanie danych wyjściowych

W Startup.Configurepliku ustaw opcję delegata HealthCheckOptions.ResponseWriter na potrzeby pisania odpowiedzi:

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

Domyślny delegat zapisuje minimalną odpowiedź w postaci zwykłego tekstu z wartością HealthReport.Statusciągu . Następujący delegat niestandardowy zwraca niestandardową odpowiedź JSON.

Pierwszy przykład z przykładowej aplikacji pokazuje, jak używać polecenia 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);
    }
}

W drugim przykładzie pokazano, jak używać polecenia 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));
}

W przykładowej aplikacji oznacz jako komentarz dyrektywę SYSTEM_TEXT_JSON preprocesora w pliku , CustomWriterStartup.cs aby włączyć Newtonsoft.Json wersję .WriteResponse

Interfejs API sprawdzania kondycji nie zapewnia wbudowanej obsługi złożonych formatów zwracanych JSON, ponieważ format jest specyficzny dla wybranego systemu monitorowania. Dostosuj odpowiedź w poprzednich przykładach zgodnie z potrzebami. Aby uzyskać więcej informacji na temat serializacji JSON za pomocą System.Text.Jsonprogramu , zobacz Jak serializować i deserializować kod JSON na platformie .NET.

Sonda bazy danych

Kontrola kondycji może określić zapytanie bazy danych do uruchomienia jako test logiczny, aby wskazać, czy baza danych odpowiada normalnie.

Przykładowa aplikacja używa AspNetCore.Diagnostics.HealthChecksbiblioteki kontroli kondycji dla aplikacji ASP.NET Core do uruchamiania kontroli kondycji bazy danych programu SQL Server. AspNetCore.Diagnostics.HealthChecksSELECT 1 Wykonuje zapytanie względem bazy danych, aby potwierdzić, że połączenie z bazą danych jest w dobrej kondycji.

Ostrzeżenie

Podczas sprawdzania połączenia bazy danych z zapytaniem wybierz zapytanie, które szybko zwraca. Podejście do zapytania powoduje przeciążenie bazy danych i obniżenie wydajności. W większości przypadków uruchomienie zapytania testowego nie jest konieczne. Wystarczy nawiązać pomyślne połączenie z bazą danych. Jeśli okaże się, że konieczne jest uruchomienie zapytania, wybierz proste zapytanie SELECT, takie jak SELECT 1.

Dołącz odwołanie do pakietu do AspNetCore.HealthChecks.SqlServerelementu .

Podaj prawidłową bazę danych parametry połączenia w appsettings.json pliku przykładowej aplikacji. Aplikacja używa bazy danych programu SQL Server o nazwie 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": "*"
}

Zarejestruj usługi sprawdzania kondycji za pomocą AddHealthChecks polecenia w programie Startup.ConfigureServices. Przykładowa aplikacja wywołuje metodę AddSqlServer z parametry połączenia bazy danych (DbHealthStartup.cs):

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

Punkt końcowy kontroli kondycji jest tworzony przez wywołanie metody MapHealthChecks w pliku Startup.Configure:

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

Aby uruchomić scenariusz sondy bazy danych przy użyciu przykładowej aplikacji, wykonaj następujące polecenie z folderu projektu w powłoce poleceń:

dotnet run --scenario db

Uwaga

AspNetCore.Diagnostics.HealthChecks firma Microsoft nie jest obsługiwana ani obsługiwana.

Sonda DbContext platformy Entity Framework Core

Sprawdzanie DbContext potwierdza, że aplikacja może komunikować się z bazą danych skonfigurowaną dla elementu EF CoreDbContext. Sprawdzanie DbContext jest obsługiwane w aplikacjach, które:

AddDbContextCheck<TContext> rejestruje kontrolę kondycji dla elementu DbContext. Parametr DbContext jest dostarczany jako TContext metoda . Przeciążenie jest dostępne do skonfigurowania stanu niepowodzenia, tagów i niestandardowego zapytania testowego.

Domyślnie:

  • Wywołania DbContextHealthCheck EF CoreCanConnectAsync metody . Możesz dostosować operację uruchamianą podczas sprawdzania kondycji przy użyciu AddDbContextCheck przeciążeń metod.
  • Nazwa sprawdzania kondycji to nazwa TContext typu.

W przykładowej aplikacji AppDbContext jest dostarczana do AddDbContextCheck usługi i zarejestrowana jako usługa w programie Startup.ConfigureServices (DbContextHealthStartup.cs):

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

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

Punkt końcowy kontroli kondycji jest tworzony przez wywołanie metody MapHealthChecks w pliku Startup.Configure:

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

Aby uruchomić DbContext scenariusz sondowania przy użyciu przykładowej aplikacji, upewnij się, że baza danych określona przez parametry połączenia nie istnieje w wystąpieniu programu SQL Server. Jeśli baza danych istnieje, usuń ją.

Wykonaj następujące polecenie z folderu projektu w powłoce poleceń:

dotnet run --scenario dbcontext

Po uruchomieniu aplikacji sprawdź stan kondycji, wysyłając żądanie do punktu końcowego /health w przeglądarce. Baza danych i AppDbContext nie istnieją, dlatego aplikacja udostępnia następującą odpowiedź:

Unhealthy

Wyzwól przykładową aplikację, aby utworzyć bazę danych. Prześlij żądanie do /createdatabase. Aplikacja odpowiada:

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

Prześlij żądanie do punktu końcowego /health . Baza danych i kontekst istnieją, więc aplikacja odpowiada:

Healthy

Wyzwól przykładową aplikację, aby usunąć bazę danych. Prześlij żądanie do /deletedatabase. Aplikacja odpowiada:

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

Prześlij żądanie do punktu końcowego /health . Aplikacja udostępnia odpowiedź w złej kondycji:

Unhealthy

Oddzielne sondy gotowości i aktualności

W niektórych scenariuszach hostingu para kontroli kondycji służy do rozróżniania dwóch stanów aplikacji:

  • Gotowość wskazuje, czy aplikacja działa normalnie, ale nie jest gotowa do odbierania żądań.
  • Liveness wskazuje, czy aplikacja uległa awarii i musi zostać ponownie uruchomiona.

Rozważmy następujący przykład: Aplikacja musi pobrać duży plik konfiguracji, zanim będzie gotowa do przetwarzania żądań. Nie chcemy, aby aplikacja została ponownie uruchomiona, jeśli początkowe pobieranie nie powiedzie się, ponieważ aplikacja może ponowić próbę pobrania pliku kilka razy. Używamy sondy liveness do opisania aktualności procesu, nie są uruchamiane żadne inne testy. Chcemy również uniemożliwić wysyłanie żądań do aplikacji przed pomyślnym pobraniem pliku konfiguracji. Używamy sondy gotowości, aby wskazać stan "nie jest gotowy", dopóki pobieranie nie powiedzie się, a aplikacja będzie gotowa do odbierania żądań.

Przykładowa aplikacja zawiera kontrolę kondycji, aby zgłosić ukończenie długotrwałego zadania uruchamiania w usłudze hostowanej. Właściwość StartupHostedServiceHealthCheck uwidacznia właściwość , StartupTaskCompletedktórą może ustawić hostowana usługa po true zakończeniu długotrwałego zadania (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."));
    }
}

Długotrwałe zadanie w tle jest uruchamiane przez usługę hostowaną (Services/StartupHostedService). Na zakończenie zadania StartupHostedServiceHealthCheck.StartupTaskCompleted ustawiono wartość 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 kondycji jest zarejestrowana AddCheck razem Startup.ConfigureServices z hostowaną usługą. Ponieważ hostowana usługa musi ustawić właściwość sprawdzania kondycji, kontrola kondycji jest również zarejestrowana w kontenerze usługi (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>();

Punkt końcowy sprawdzania kondycji jest tworzony przez wywołanie metody MapHealthChecks w pliku Startup.Configure. W przykładowej aplikacji punkty końcowe sprawdzania kondycji są tworzone pod adresem:

  • /health/ready w celu sprawdzenia gotowości. Test gotowości filtruje testy kondycji do sprawdzania kondycji za pomocą tagu ready .
  • /health/live w celu sprawdzenia aktualności. Sprawdzanie aktualności filtruje StartupHostedServiceHealthCheck element, wracając false do HealthCheckOptions.Predicate elementu (aby uzyskać więcej informacji, zobacz Filtrowanie kontroli kondycji)

W poniższym przykładowym kodzie:

  • Sprawdzanie gotowości używa wszystkich zarejestrowanych testów z tagiem "ready".
  • Element Predicate wyklucza wszystkie kontrole i zwraca wartość 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
    });
}

Aby uruchomić scenariusz konfiguracji gotowości/żywości przy użyciu przykładowej aplikacji, wykonaj następujące polecenie z folderu projektu w powłoce poleceń:

dotnet run --scenario liveness

W przeglądarce przejdź /health/ready kilka razy do 15 sekund. Raporty kontroli Unhealthy kondycji przez pierwsze 15 sekund. Po 15 sekundach punkt końcowy zgłasza Healthywartość , która odzwierciedla ukończenie długotrwałego zadania przez hostowaną usługę.

W tym przykładzie zostanie również utworzony program Health Check Publisher (IHealthCheckPublisher implementacja), który uruchamia pierwszą kontrolę gotowości z dwusekundowym opóźnieniem. Aby uzyskać więcej informacji, zobacz sekcję Health Check Publisher (Wydawca sprawdzania kondycji).

Przykład rozwiązania Kubernetes

Korzystanie z oddzielnych testów gotowości i dostępności jest przydatne w środowisku, takim jak Kubernetes. Na platformie Kubernetes aplikacja może być wymagana do wykonywania czasochłonnej pracy podczas uruchamiania przed zaakceptowaniem żądań, takich jak test dostępności bazowej bazy danych. Użycie oddzielnych kontroli umożliwia orkiestratorowi rozróżnienie, czy aplikacja działa, ale nie jest jeszcze gotowa, czy nie można uruchomić aplikacji. Aby uzyskać więcej informacji na temat sond gotowości i aktualności na platformie Kubernetes, zobacz Konfigurowanie sondy kondycji i gotowości w dokumentacji platformy Kubernetes.

W poniższym przykładzie pokazano konfigurację sondy gotowości platformy 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 oparta na metryce z niestandardowym modułem zapisywania odpowiedzi

Przykładowa aplikacja demonstruje kontrolę kondycji pamięci z niestandardowym modułem zapisywania odpowiedzi.

MemoryHealthCheck zgłasza stan obniżonej wydajności, jeśli aplikacja używa więcej niż określony próg pamięci (1 GB w przykładowej aplikacji). Zawiera HealthCheckResult informacje dotyczące modułu odśmieceń pamięci (GC) dla aplikacji (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));
    }
}

Zarejestruj usługi sprawdzania kondycji za pomocą AddHealthChecks polecenia w programie Startup.ConfigureServices. Zamiast włączać kontrolę kondycji, przekazując ją do AddCheckelementu , MemoryHealthCheck element jest zarejestrowany jako usługa. Wszystkie IHealthCheck zarejestrowane usługi są dostępne dla usług kontroli kondycji i oprogramowania pośredniczącego. Zalecamy zarejestrowanie usług kontroli kondycji jako usług Singleton.

W CustomWriterStartup.cs przykładowej aplikacji:

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

Punkt końcowy sprawdzania kondycji jest tworzony przez wywołanie metody MapHealthChecks w pliku Startup.Configure. Delegat WriteResponse jest dostarczany do ResponseWriter właściwości w celu wyprowadzenia niestandardowej odpowiedzi JSON po wykonaniu sprawdzania kondycji:

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

Delegat WriteResponse formatuje CompositeHealthCheckResult obiekt w obiekcie JSON i zwraca dane wyjściowe JSON dla odpowiedzi kontroli kondycji. Aby uzyskać więcej informacji, zobacz sekcję Dostosowywanie danych wyjściowych .

Aby uruchomić sondę opartą na metrykach z niestandardowymi danymi wyjściowymi modułu zapisywania odpowiedzi przy użyciu przykładowej aplikacji, wykonaj następujące polecenie z folderu projektu w powłoce poleceń:

dotnet run --scenario writer

Uwaga

AspNetCore.Diagnostics.HealthChecks obejmuje scenariusze sprawdzania kondycji oparte na metrykach, w tym magazyn dysku i testy wydajności maksymalnej wartości.

AspNetCore.Diagnostics.HealthChecks firma Microsoft nie jest obsługiwana ani obsługiwana.

Filtruj według portu

Wywołaj metodę RequireHost przy MapHealthChecks użyciu wzorca adresu URL, który określa port w celu ograniczenia żądań kontroli kondycji do określonego portu. Takie podejście jest zwykle używane w środowisku kontenera do uwidaczniania portu na potrzeby usług monitorowania.

Przykładowa aplikacja konfiguruje port przy użyciu dostawcy konfiguracji zmiennej środowiskowej. Port jest ustawiany w launchSettings.json pliku i przekazywany do dostawcy konfiguracji za pośrednictwem zmiennej środowiskowej. Należy również skonfigurować serwer do nasłuchiwania żądań na porcie zarządzania.

Aby użyć przykładowej aplikacji do zademonstrowania konfiguracji portu zarządzania, utwórz launchSettings.json plik w folderze Properties .

Następujący Properties/launchSettings.json plik w przykładowej aplikacji nie jest uwzględniony w plikach projektu przykładowej aplikacji i należy go utworzyć ręcznie:

{
  "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/"
    }
  }
}

Zarejestruj usługi sprawdzania kondycji za pomocą AddHealthChecks polecenia w programie Startup.ConfigureServices. Utwórz punkt końcowy kontroli kondycji, wywołując polecenie MapHealthChecks w pliku Startup.Configure.

W przykładowej aplikacji wywołanie do RequireHost punktu końcowego w programie Startup.Configure określa port zarządzania z konfiguracji:

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

Punkty końcowe są tworzone w przykładowej aplikacji w programie Startup.Configure. W poniższym przykładowym kodzie:

  • Sprawdzanie gotowości używa wszystkich zarejestrowanych testów z tagiem "ready".
  • Element Predicate wyklucza wszystkie kontrole i zwraca wartość 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
    });
}

Uwaga

Możesz uniknąć tworzenia launchSettings.json pliku w przykładowej aplikacji, ustawiając jawnie port zarządzania w kodzie. W Program.cs miejscu utworzenia HostBuilder dodaj wywołanie i ListenAnyIP podaj punkt końcowy portu zarządzania aplikacji. W Configure pliku ManagementPortStartup.csokreśl port zarządzania za pomocą RequireHostpolecenia :

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

Aby uruchomić scenariusz konfiguracji portu zarządzania przy użyciu przykładowej aplikacji, wykonaj następujące polecenie z folderu projektu w powłoce poleceń:

dotnet run --scenario port

Rozpowszechnianie biblioteki kontroli kondycji

Aby rozpowszechnić kontrolę kondycji jako bibliotekę:

  1. Napisz kontrolę kondycji, która implementuje IHealthCheck interfejs jako klasę autonomiczną. Klasa może polegać na iniekcji zależności (DI), aktywacji typu i nazwanych opcjach uzyskiwania dostępu do danych konfiguracji.

    W logice kontroli kondycji elementu CheckHealthAsync:

    • data1 i data2 są używane w metodzie do uruchamiania logiki sprawdzania kondycji sondy.
    • AccessViolationException jest obsługiwana.

    W przypadku AccessViolationException wystąpienia FailureStatus element jest zwracany z parametrem HealthCheckResult , aby umożliwić użytkownikom skonfigurowanie stanu niepowodzenia kontroli kondycji.

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Extensions.Diagnostics.HealthChecks;
    
    namespace SampleApp
    {
        public class ExampleHealthCheck : IHealthCheck
        {
            private readonly string _data1;
            private readonly int? _data2;
    
            public ExampleHealthCheck(string data1, int? data2)
            {
                _data1 = data1 ?? throw new ArgumentNullException(nameof(data1));
                _data2 = data2 ?? throw new ArgumentNullException(nameof(data2));
            }
    
            public async Task<HealthCheckResult> CheckHealthAsync(
                HealthCheckContext context, CancellationToken cancellationToken)
            {
                try
                {
                    return HealthCheckResult.Healthy();
                }
                catch (AccessViolationException ex)
                {
                    return new HealthCheckResult(
                        context.Registration.FailureStatus,
                        description: "An access violation occurred during the check.",
                        exception: ex,
                        data: null);
                }
            }
        }
    }
    
  2. Napisz metodę rozszerzenia z parametrami, które aplikacja zużywającą wywołuje w swojej Startup.Configure metodzie. W poniższym przykładzie przyjęto założenie, że podpis następującej metody sprawdzania kondycji:

    ExampleHealthCheck(string, string, int )
    

    Powyższy podpis wskazuje, że ExampleHealthCheck wymagane są dodatkowe dane do przetwarzania logiki sondy sprawdzania kondycji. Dane są udostępniane delegatowi użytemu do utworzenia wystąpienia kontroli kondycji po zarejestrowaniu sprawdzania kondycji za pomocą metody rozszerzenia. W poniższym przykładzie obiekt wywołujący określa opcjonalne:

    • nazwa kontroli kondycji (name). example_health_check Jeśli nullparametr jest używany.
    • punkt danych ciągu dla kontroli kondycji (data1).
    • Punkt danych liczby całkowitej dla kontroli kondycji (data2). 1 Jeśli nullparametr jest używany.
    • stan błędu (HealthStatus). Wartość domyślna to null. Jeśli nullparametr HealthStatus.Unhealthy jest zgłaszany jako stan niepowodzenia.
    • tagi (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));
        }
    }
    

Wydawca kontroli kondycji

Po dodaniu elementu IHealthCheckPublisher do kontenera usługi system sprawdzania kondycji okresowo wykonuje testy kondycji i wywołuje PublishAsync wynik. Jest to przydatne w scenariuszu systemu monitorowania kondycji opartego na wypychaniu, który oczekuje, że każdy proces będzie okresowo wywoływać system monitorowania w celu określenia kondycji.

Interfejs IHealthCheckPublisher ma jedną metodę:

Task PublishAsync(HealthReport report, CancellationToken cancellationToken);

HealthCheckPublisherOptions zezwalaj na ustawienie:

  • Delay: początkowe opóźnienie zastosowane po uruchomieniu aplikacji przed wykonaniem IHealthCheckPublisher wystąpień. Opóźnienie jest stosowane raz podczas uruchamiania i nie ma zastosowania do kolejnych iteracji. Wartość domyślna to pięć sekund.
  • Period: okres IHealthCheckPublisher wykonywania. Wartość domyślna to 30 sekund.
  • Predicate: Jeśli Predicate jest null (wartość domyślna), usługa wydawcy sprawdzania kondycji uruchamia wszystkie zarejestrowane testy kondycji. Aby uruchomić podzbiór kontroli kondycji, podaj funkcję, która filtruje zestaw testów. Predykat jest obliczany w każdym okresie.
  • Timeout: limit czasu wykonywania kontroli kondycji dla wszystkich IHealthCheckPublisher wystąpień. Użyj polecenia InfiniteTimeSpan , aby wykonać bez limitu czasu. Wartość domyślna to 30 sekund.

W przykładowej aplikacji ReadinessPublisher jest implementacją IHealthCheckPublisher . Stan kontroli kondycji jest rejestrowany dla każdego sprawdzenia na poziomie dziennika:

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

W przykładzie StartupHostedService przykładowej aplikacji LivenessProbeStartup test gotowości ma dwa sekundy opóźnienia uruchamiania i uruchamia sprawdzanie co 30 sekund. Aby aktywować implementacjęIHealthCheckPublisher, przykład rejestruje ReadinessPublisher się jako usługa pojedyncza w kontenerze wstrzykiwania zależności (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>();

Uwaga

AspNetCore.Diagnostics.HealthChecks zawiera wydawców dla kilku systemów, w tym usługi Application Insights.

AspNetCore.Diagnostics.HealthChecks firma Microsoft nie jest obsługiwana ani obsługiwana.

Ograniczanie kontroli kondycji za pomocą polecenia MapWhen

Użyj polecenia MapWhen , aby warunkowo rozgałęzić potok żądania dla punktów końcowych sprawdzania kondycji.

W poniższym przykładzie potok żądania jest odgałęzieny w MapWhen celu aktywowania oprogramowania pośredniczącego sprawdzania kondycji, jeśli żądanie GET zostanie odebrane dla punktu końcowego api/HealthCheck :

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

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

Aby uzyskać więcej informacji, zobacz Oprogramowanie pośredniczące ASP.NET Core.

ASP.NET Core oferuje oprogramowanie pośredniczące kontroli kondycji i biblioteki do raportowania kondycji składników infrastruktury aplikacji.

Testy kondycji są udostępniane przez aplikację jako punkty końcowe HTTP. Punkty końcowe kontroli kondycji można skonfigurować dla różnych scenariuszy monitorowania w czasie rzeczywistym:

  • Sondy kondycji mogą być używane przez koordynatorów kontenerów i moduły równoważenia obciążenia w celu sprawdzenia stanu aplikacji. Na przykład orkiestrator kontenerów może reagować na niepowodzenie sprawdzania kondycji, zatrzymując wdrożenie stopniowe lub ponownie uruchamiając kontener. Moduł równoważenia obciążenia może reagować na aplikację w złej kondycji, rozsyłając ruch z dala od wystąpienia w dobrej kondycji.
  • Użycie pamięci, dysku i innych zasobów serwera fizycznego można monitorować pod kątem stanu dobrej kondycji.
  • Testy kondycji mogą testować zależności aplikacji, takie jak bazy danych i zewnętrzne punkty końcowe usługi, w celu potwierdzenia dostępności i normalnego działania.

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Przykładowa aplikacja zawiera przykłady scenariuszy opisanych w tym artykule. Aby uruchomić przykładową aplikację dla danego scenariusza, użyj polecenia dotnet run z folderu projektu w powłoce poleceń. Zobacz plik przykładowej README.md aplikacji i opisy scenariuszy w tym artykule, aby uzyskać szczegółowe informacje na temat korzystania z przykładowej aplikacji.

Wymagania wstępne

Testy kondycji są zwykle używane z zewnętrzną usługą monitorowania lub koordynatorem kontenerów w celu sprawdzenia stanu aplikacji. Przed dodaniem kontroli kondycji do aplikacji zdecyduj, który system monitorowania ma być używany. System monitorowania określa typy kontroli kondycji do utworzenia i sposobu konfigurowania ich punktów końcowych.

Pakiet Microsoft.AspNetCore.Diagnostics.HealthChecks jest przywołyyny niejawnie dla aplikacji ASP.NET Core. Aby uruchomić kontrole kondycji przy użyciu programu Entity Framework Core, dodaj odwołanie do Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore pakietu.

Przykładowa aplikacja udostępnia kod uruchamiania w celu zademonstrowania kontroli kondycji dla kilku scenariuszy. Scenariusz sondy bazy danych sprawdza kondycję połączenia z bazą danych przy użyciu polecenia AspNetCore.Diagnostics.HealthChecks. Scenariusz sondy DbContext sprawdza bazę danych przy użyciu elementu EF CoreDbContext. Aby zapoznać się ze scenariuszami bazy danych, przykładowa aplikacja:

Uwaga

AspNetCore.Diagnostics.HealthChecks firma Microsoft nie jest obsługiwana ani obsługiwana.

Inny scenariusz kontroli kondycji przedstawia sposób filtrowania kontroli kondycji na porcie zarządzania. Przykładowa aplikacja wymaga utworzenia pliku zawierającego Properties/launchSettings.json adres URL zarządzania i port zarządzania. Aby uzyskać więcej informacji, zobacz sekcję Filtruj według portów .

Podstawowa sonda kondycji

W przypadku wielu aplikacji podstawowa konfiguracja sondy kondycji, która zgłasza dostępność aplikacji do przetwarzania żądań (żywości) jest wystarczająca do odnalezienia stanu aplikacji.

Podstawowa konfiguracja rejestruje usługi sprawdzania kondycji i wywołuje oprogramowanie pośredniczące kontroli kondycji, aby odpowiedzieć w punkcie końcowym adresu URL z odpowiedzią na kondycję. Domyślnie żadne konkretne kontrole kondycji nie są rejestrowane w celu przetestowania żadnej konkretnej zależności lub podsystemu. Aplikacja jest uważana za w dobrej kondycji, jeśli może odpowiadać pod adresem URL punktu końcowego kondycji. Domyślny składnik zapisywania odpowiedzi zapisuje stan (HealthStatus) jako odpowiedź w postaci zwykłego tekstu z powrotem do klienta, wskazując stan HealthStatus.Healthy, HealthStatus.Degradedlub HealthStatus.Unhealthy .

Zarejestruj usługi sprawdzania kondycji za pomocą AddHealthChecks polecenia w programie Startup.ConfigureServices. Utwórz punkt końcowy kontroli kondycji, wywołując polecenie MapHealthChecks w pliku Startup.Configure.

W przykładowej aplikacji punkt końcowy sprawdzania kondycji jest tworzony pod adresem /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");
        });
    }
}

Aby uruchomić podstawowy scenariusz konfiguracji przy użyciu przykładowej aplikacji, wykonaj następujące polecenie z folderu projektu w powłoce poleceń:

dotnet run --scenario basic

Przykład platformy Docker

Platforma Docker oferuje wbudowaną HEALTHCHECK dyrektywę, która może służyć do sprawdzania stanu aplikacji korzystającej z podstawowej konfiguracji kontroli kondycji:

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

Tworzenie kontroli kondycji

Testy kondycji są tworzone przez zaimplementowanie interfejsu IHealthCheck . Metoda CheckHealthAsync zwraca wartość HealthCheckResult , która wskazuje kondycję jako Healthy, Degradedlub Unhealthy. Wynik jest zapisywany jako odpowiedź w postaci zwykłego tekstu z konfigurowalnym kodem stanu (konfiguracja jest opisana w sekcji Opcje sprawdzania kondycji). HealthCheckResult może również zwracać opcjonalne pary klucz-wartość.

Poniższa ExampleHealthCheck klasa demonstruje układ kontroli kondycji. Logika kontroli kondycji jest umieszczana w metodzie CheckHealthAsync . W poniższym przykładzie ustawiono fikcyjną zmienną , healthCheckResultHealthyna true. Jeśli wartość parametru healthCheckResultHealthy jest ustawiona na falsewartość , HealthCheckResult.Unhealthy zwracany jest stan.

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

Rejestrowanie usług kontroli kondycji

Typ jest dodawany do usług sprawdzania ExampleHealthCheck kondycji za pomocą AddCheck polecenia w pliku :Startup.ConfigureServices

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

Przeciążenie AddCheck pokazane w poniższym przykładzie ustawia stan błędu (HealthStatus) w celu raportowania, gdy kontrola kondycji zgłasza błąd. Jeśli stan niepowodzenia jest ustawiony na null (wartość domyślna), HealthStatus.Unhealthy jest zgłaszany. To przeciążenie jest przydatnym scenariuszem dla autorów bibliotek, w którym stan awarii wskazywany przez bibliotekę jest wymuszany przez aplikację, gdy wystąpi błąd sprawdzania kondycji, jeśli implementacja kontroli kondycji honoruje ustawienie.

Tagi mogą służyć do filtrowania kontroli kondycji (opisanych dalej w sekcji Kontrole kondycji filtru).

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

AddCheck może również wykonać funkcję lambda. W poniższym przykładzie nazwa kontroli kondycji jest określona jako Example i sprawdzanie zawsze zwraca stan dobrej kondycji:

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

Wywołaj metodę AddTypeActivatedCheck , aby przekazać argumenty do implementacji kontroli kondycji. W poniższym przykładzie TestHealthCheckWithArgs akceptuje liczbę całkowitą i ciąg do użycia, gdy CheckHealthAsync jest wywoływany:

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 jest rejestrowany przez wywołanie AddTypeActivatedCheck za pomocą liczby całkowitej i ciągu przekazanego do implementacji:

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

Używanie routingu sprawdzania kondycji

W Startup.Configurepliku wywołaj MapHealthChecks konstruktora punktu końcowego przy użyciu adresu URL punktu końcowego lub ścieżki względnej:

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

Wymagaj hosta

Wywołaj metodę RequireHost , aby określić co najmniej jeden dozwolony host dla punktu końcowego kontroli kondycji. Hosty powinny być unicode, a nie punycode i mogą zawierać port. Jeśli kolekcja nie zostanie dostarczona, zostanie zaakceptowany żaden host.

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

Aby uzyskać więcej informacji, zobacz sekcję Filtruj według portów .

Wymagaj autoryzacji

Wywołaj polecenie RequireAuthorization , aby uruchomić oprogramowanie pośredniczące autoryzacji w punkcie końcowym żądania sprawdzania kondycji. Przeciążenie RequireAuthorization akceptuje co najmniej jedną zasady autoryzacji. Jeśli nie podano zasad, są używane domyślne zasady autoryzacji.

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

Włączanie żądań Cross-Origin (CORS)

Mimo że ręczne uruchamianie kontroli kondycji z przeglądarki nie jest typowym scenariuszem użycia, oprogramowanie pośredniczące CORS można włączyć przez wywołanie RequireCors punktów końcowych kontroli kondycji. Przeciążenie RequireCors akceptuje delegata konstruktora zasad CORS (CorsPolicyBuilder) lub nazwę zasad. Jeśli nie podano zasad, zostanie użyta domyślna zasada CORS. Aby uzyskać więcej informacji, zobacz Włączanie żądań między źródłami (CORS) w ASP.NET Core.

Opcje kontroli kondycji

HealthCheckOptions umożliwia dostosowanie zachowania kontroli kondycji:

Filtrowanie kontroli kondycji

Domyślnie oprogramowanie pośredniczące sprawdzania kondycji uruchamia wszystkie zarejestrowane testy kondycji. Aby uruchomić podzbiór kontroli kondycji, podaj funkcję, która zwraca wartość logiczną do Predicate opcji. W poniższym przykładzie Bar sprawdzanie kondycji jest filtrowane według tagu (bar_tag) w instrukcji warunkowej funkcji, gdzie true jest zwracana tylko wtedy, gdy właściwość sprawdzania kondycji Tags jest zgodna foo_tag z właściwością lub baz_tag:

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

W Startup.Configurepliku filtruje Predicate sprawdzanie kondycji paska. Wykonaj tylko polecenia Foo i Baz:

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

Dostosowywanie kodu stanu HTTP

Służy ResultStatusCodes do dostosowywania mapowania stanu kondycji na kody stanu HTTP. Następujące StatusCodes przypisania są wartościami domyślnymi używanymi przez oprogramowanie pośredniczące. Zmień wartości kodu stanu, aby spełniały twoje wymagania.

W pliku Startup.Configure:

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

Pomijanie nagłówków pamięci podręcznej

AllowCachingResponses określa, czy oprogramowanie pośredniczące kontroli kondycji dodaje nagłówki HTTP do odpowiedzi sondy, aby zapobiec buforowaniu odpowiedzi. Jeśli wartość to false (wartość domyślna), oprogramowanie pośredniczące ustawia lub zastępuje Cache-Controlnagłówki , Expiresi Pragma , aby zapobiec buforowaniu odpowiedzi. Jeśli wartość to true, oprogramowanie pośredniczące nie modyfikuje nagłówków pamięci podręcznej odpowiedzi.

W pliku Startup.Configure:

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

Dostosowywanie danych wyjściowych

W Startup.Configurepliku ustaw opcję delegata HealthCheckOptions.ResponseWriter na potrzeby pisania odpowiedzi:

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

Domyślny delegat zapisuje minimalną odpowiedź w postaci zwykłego tekstu z wartością HealthReport.Statusciągu . Następujący delegat niestandardowy zwraca niestandardową odpowiedź JSON.

Pierwszy przykład z przykładowej aplikacji pokazuje, jak używać polecenia 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);
    }
}

W drugim przykładzie pokazano, jak używać pliku 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));
}

W przykładowej aplikacji oznacz jako komentarz dyrektywę SYSTEM_TEXT_JSON preprocesora w pliku , CustomWriterStartup.cs aby włączyć Newtonsoft.Json wersję .WriteResponse

Interfejs API sprawdzania kondycji nie zapewnia wbudowanej obsługi złożonych formatów zwracanych JSON, ponieważ format jest specyficzny dla wybranego systemu monitorowania. Dostosuj odpowiedź w poprzednich przykładach zgodnie z potrzebami. Aby uzyskać więcej informacji na temat serializacji JSON za pomocą System.Text.Jsonprogramu , zobacz Jak serializować i deserializować kod JSON na platformie .NET.

Sonda bazy danych

Kontrola kondycji może określić zapytanie bazy danych do uruchomienia jako test logiczny, aby wskazać, czy baza danych odpowiada normalnie.

Przykładowa aplikacja używa AspNetCore.Diagnostics.HealthChecksbiblioteki kontroli kondycji dla aplikacji ASP.NET Core do uruchamiania kontroli kondycji bazy danych programu SQL Server. AspNetCore.Diagnostics.HealthChecksSELECT 1 Wykonuje zapytanie względem bazy danych, aby potwierdzić, że połączenie z bazą danych jest w dobrej kondycji.

Ostrzeżenie

Podczas sprawdzania połączenia bazy danych z zapytaniem wybierz zapytanie, które szybko zwraca. Podejście do zapytania powoduje przeciążenie bazy danych i obniżenie wydajności. W większości przypadków uruchomienie zapytania testowego nie jest konieczne. Wystarczy nawiązać pomyślne połączenie z bazą danych. Jeśli okaże się, że konieczne jest uruchomienie zapytania, wybierz proste zapytanie SELECT, takie jak SELECT 1.

Dołącz odwołanie do pakietu do AspNetCore.HealthChecks.SqlServerelementu .

Podaj prawidłową bazę danych parametry połączenia w appsettings.json pliku przykładowej aplikacji. Aplikacja używa bazy danych programu SQL Server o nazwie 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": "*"
}

Zarejestruj usługi sprawdzania kondycji za pomocą AddHealthChecks polecenia w programie Startup.ConfigureServices. Przykładowa aplikacja wywołuje metodę AddSqlServer z parametry połączenia bazy danych (DbHealthStartup.cs):

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

Punkt końcowy kontroli kondycji jest tworzony przez wywołanie metody MapHealthChecks w pliku Startup.Configure:

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

Aby uruchomić scenariusz sondy bazy danych przy użyciu przykładowej aplikacji, wykonaj następujące polecenie z folderu projektu w powłoce poleceń:

dotnet run --scenario db

Uwaga

AspNetCore.Diagnostics.HealthChecks firma Microsoft nie jest obsługiwana ani obsługiwana.

Sonda DbContext platformy Entity Framework Core

Sprawdzanie DbContext potwierdza, że aplikacja może komunikować się z bazą danych skonfigurowaną dla elementu EF CoreDbContext. Sprawdzanie DbContext jest obsługiwane w aplikacjach, które:

AddDbContextCheck<TContext> rejestruje kontrolę kondycji dla elementu DbContext. Parametr DbContext jest dostarczany jako TContext metoda . Przeciążenie jest dostępne do skonfigurowania stanu niepowodzenia, tagów i niestandardowego zapytania testowego.

Domyślnie:

  • Wywołania DbContextHealthCheck EF CoreCanConnectAsync metody . Możesz dostosować operację uruchamianą podczas sprawdzania kondycji przy użyciu AddDbContextCheck przeciążeń metod.
  • Nazwa sprawdzania kondycji to nazwa TContext typu.

W przykładowej aplikacji AppDbContext jest dostarczana do AddDbContextCheck usługi i zarejestrowana jako usługa w programie Startup.ConfigureServices (DbContextHealthStartup.cs):

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

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

Punkt końcowy kontroli kondycji jest tworzony przez wywołanie metody MapHealthChecks w pliku Startup.Configure:

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

Aby uruchomić DbContext scenariusz sondowania przy użyciu przykładowej aplikacji, upewnij się, że baza danych określona przez parametry połączenia nie istnieje w wystąpieniu programu SQL Server. Jeśli baza danych istnieje, usuń ją.

Wykonaj następujące polecenie z folderu projektu w powłoce poleceń:

dotnet run --scenario dbcontext

Po uruchomieniu aplikacji sprawdź stan kondycji, wysyłając żądanie do punktu końcowego /health w przeglądarce. Baza danych i AppDbContext nie istnieją, dlatego aplikacja udostępnia następującą odpowiedź:

Unhealthy

Wyzwól przykładową aplikację, aby utworzyć bazę danych. Prześlij żądanie do /createdatabase. Aplikacja odpowiada:

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

Prześlij żądanie do punktu końcowego /health . Baza danych i kontekst istnieją, więc aplikacja odpowiada:

Healthy

Wyzwól przykładową aplikację, aby usunąć bazę danych. Prześlij żądanie do /deletedatabase. Aplikacja odpowiada:

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

Prześlij żądanie do punktu końcowego /health . Aplikacja udostępnia odpowiedź w złej kondycji:

Unhealthy

Oddzielne sondy gotowości i aktualności

W niektórych scenariuszach hostingu para kontroli kondycji służy do rozróżniania dwóch stanów aplikacji:

  • Gotowość wskazuje, czy aplikacja działa normalnie, ale nie jest gotowa do odbierania żądań.
  • Liveness wskazuje, czy aplikacja uległa awarii i musi zostać ponownie uruchomiona.

Rozważmy następujący przykład: Aplikacja musi pobrać duży plik konfiguracji, zanim będzie gotowa do przetwarzania żądań. Nie chcemy, aby aplikacja została ponownie uruchomiona, jeśli początkowe pobieranie nie powiedzie się, ponieważ aplikacja może ponowić próbę pobrania pliku kilka razy. Używamy sondy liveness do opisania aktualności procesu, nie są uruchamiane żadne inne testy. Chcemy również uniemożliwić wysyłanie żądań do aplikacji przed pomyślnym pobraniem pliku konfiguracji. Używamy sondy gotowości, aby wskazać stan "nie jest gotowy", dopóki pobieranie nie powiedzie się, a aplikacja będzie gotowa do odbierania żądań.

Przykładowa aplikacja zawiera kontrolę kondycji, aby zgłosić ukończenie długotrwałego zadania uruchamiania w usłudze hostowanej. Właściwość StartupHostedServiceHealthCheck uwidacznia właściwość , StartupTaskCompletedktórą może ustawić hostowana usługa po true zakończeniu długotrwałego zadania (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."));
    }
}

Długotrwałe zadanie w tle jest uruchamiane przez usługę hostowaną (Services/StartupHostedService). Na zakończenie zadania StartupHostedServiceHealthCheck.StartupTaskCompleted ustawiono wartość 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 kondycji jest zarejestrowana AddCheck razem Startup.ConfigureServices z hostowaną usługą. Ponieważ hostowana usługa musi ustawić właściwość sprawdzania kondycji, kontrola kondycji jest również zarejestrowana w kontenerze usługi (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>();

Punkt końcowy sprawdzania kondycji jest tworzony przez wywołanie metody MapHealthChecks w pliku Startup.Configure. W przykładowej aplikacji punkty końcowe sprawdzania kondycji są tworzone pod adresem:

  • /health/ready w celu sprawdzenia gotowości. Test gotowości filtruje testy kondycji do sprawdzania kondycji za pomocą tagu ready .
  • /health/live w celu sprawdzenia aktualności. Sprawdzanie aktualności filtruje StartupHostedServiceHealthCheck element, wracając false do HealthCheckOptions.Predicate elementu (aby uzyskać więcej informacji, zobacz Filtrowanie kontroli kondycji)

W poniższym przykładowym kodzie:

  • Sprawdzanie gotowości używa wszystkich zarejestrowanych testów z tagiem "ready".
  • Element Predicate wyklucza wszystkie kontrole i zwraca wartość 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
    });
}

Aby uruchomić scenariusz konfiguracji gotowości/żywości przy użyciu przykładowej aplikacji, wykonaj następujące polecenie z folderu projektu w powłoce poleceń:

dotnet run --scenario liveness

W przeglądarce przejdź /health/ready kilka razy do 15 sekund. Raporty kontroli Unhealthy kondycji przez pierwsze 15 sekund. Po 15 sekundach punkt końcowy zgłasza Healthywartość , która odzwierciedla ukończenie długotrwałego zadania przez hostowaną usługę.

W tym przykładzie zostanie również utworzony program Health Check Publisher (IHealthCheckPublisher implementacja), który uruchamia pierwszą kontrolę gotowości z dwusekundowym opóźnieniem. Aby uzyskać więcej informacji, zobacz sekcję Health Check Publisher (Wydawca sprawdzania kondycji).

Przykład rozwiązania Kubernetes

Korzystanie z oddzielnych testów gotowości i dostępności jest przydatne w środowisku, takim jak Kubernetes. Na platformie Kubernetes aplikacja może być wymagana do wykonywania czasochłonnej pracy podczas uruchamiania przed zaakceptowaniem żądań, takich jak test dostępności bazowej bazy danych. Użycie oddzielnych kontroli umożliwia orkiestratorowi rozróżnienie, czy aplikacja działa, ale nie jest jeszcze gotowa, czy nie można uruchomić aplikacji. Aby uzyskać więcej informacji na temat sond gotowości i aktualności na platformie Kubernetes, zobacz Konfigurowanie sondy kondycji i gotowości w dokumentacji platformy Kubernetes.

W poniższym przykładzie pokazano konfigurację sondy gotowości platformy 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 oparta na metryce z niestandardowym modułem zapisywania odpowiedzi

Przykładowa aplikacja demonstruje kontrolę kondycji pamięci z niestandardowym modułem zapisywania odpowiedzi.

MemoryHealthCheck zgłasza stan obniżonej wydajności, jeśli aplikacja używa więcej niż określony próg pamięci (1 GB w przykładowej aplikacji). Zawiera HealthCheckResult informacje dotyczące modułu odśmieceń pamięci (GC) dla aplikacji (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));
    }
}

Zarejestruj usługi sprawdzania kondycji za pomocą AddHealthChecks polecenia w programie Startup.ConfigureServices. Zamiast włączać kontrolę kondycji, przekazując ją do AddCheckelementu , MemoryHealthCheck element jest zarejestrowany jako usługa. Wszystkie IHealthCheck zarejestrowane usługi są dostępne dla usług kontroli kondycji i oprogramowania pośredniczącego. Zalecamy zarejestrowanie usług kontroli kondycji jako usług Singleton.

W CustomWriterStartup.cs przykładowej aplikacji:

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

Punkt końcowy sprawdzania kondycji jest tworzony przez wywołanie metody MapHealthChecks w pliku Startup.Configure. Delegat WriteResponse jest dostarczany do ResponseWriter właściwości w celu wyprowadzenia niestandardowej odpowiedzi JSON po wykonaniu sprawdzania kondycji:

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

Delegat WriteResponse formatuje CompositeHealthCheckResult obiekt w obiekcie JSON i zwraca dane wyjściowe JSON dla odpowiedzi kontroli kondycji. Aby uzyskać więcej informacji, zobacz sekcję Dostosowywanie danych wyjściowych .

Aby uruchomić sondę opartą na metrykach z niestandardowymi danymi wyjściowymi modułu zapisywania odpowiedzi przy użyciu przykładowej aplikacji, wykonaj następujące polecenie z folderu projektu w powłoce poleceń:

dotnet run --scenario writer

Uwaga

AspNetCore.Diagnostics.HealthChecks obejmuje scenariusze sprawdzania kondycji oparte na metrykach, w tym magazyn dysku i testy wydajności maksymalnej wartości.

AspNetCore.Diagnostics.HealthChecks firma Microsoft nie jest obsługiwana ani obsługiwana.

Filtruj według portu

Wywołaj metodę RequireHost przy MapHealthChecks użyciu wzorca adresu URL, który określa port w celu ograniczenia żądań kontroli kondycji do określonego portu. Takie podejście jest zwykle używane w środowisku kontenera do uwidaczniania portu na potrzeby usług monitorowania.

Przykładowa aplikacja konfiguruje port przy użyciu dostawcy konfiguracji zmiennej środowiskowej. Port jest ustawiany w launchSettings.json pliku i przekazywany do dostawcy konfiguracji za pośrednictwem zmiennej środowiskowej. Należy również skonfigurować serwer do nasłuchiwania żądań na porcie zarządzania.

Aby użyć przykładowej aplikacji do zademonstrowania konfiguracji portu zarządzania, utwórz launchSettings.json plik w folderze Properties .

Następujący Properties/launchSettings.json plik w przykładowej aplikacji nie jest uwzględniony w plikach projektu przykładowej aplikacji i należy go utworzyć ręcznie:

{
  "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/"
    }
  }
}

Zarejestruj usługi sprawdzania kondycji za pomocą AddHealthChecks polecenia w programie Startup.ConfigureServices. Utwórz punkt końcowy kontroli kondycji, wywołując polecenie MapHealthChecks w pliku Startup.Configure.

W przykładowej aplikacji wywołanie do RequireHost punktu końcowego w programie Startup.Configure określa port zarządzania z konfiguracji:

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

Punkty końcowe są tworzone w przykładowej aplikacji w programie Startup.Configure. W poniższym przykładowym kodzie:

  • Sprawdzanie gotowości używa wszystkich zarejestrowanych testów z tagiem "ready".
  • Element Predicate wyklucza wszystkie kontrole i zwraca wartość 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
    });
}

Uwaga

Możesz uniknąć tworzenia launchSettings.json pliku w przykładowej aplikacji, ustawiając jawnie port zarządzania w kodzie. W Program.cs miejscu utworzenia HostBuilder dodaj wywołanie i ListenAnyIP podaj punkt końcowy portu zarządzania aplikacji. W Configure pliku ManagementPortStartup.csokreśl port zarządzania za pomocą RequireHostpolecenia :

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

Aby uruchomić scenariusz konfiguracji portu zarządzania przy użyciu przykładowej aplikacji, wykonaj następujące polecenie z folderu projektu w powłoce poleceń:

dotnet run --scenario port

Rozpowszechnianie biblioteki kontroli kondycji

Aby rozpowszechnić kontrolę kondycji jako bibliotekę:

  1. Napisz kontrolę kondycji, która implementuje IHealthCheck interfejs jako klasę autonomiczną. Klasa może polegać na iniekcji zależności (DI), aktywacji typu i nazwanych opcjach uzyskiwania dostępu do danych konfiguracji.

    W logice kontroli kondycji elementu CheckHealthAsync:

    • data1 i data2 są używane w metodzie do uruchamiania logiki sprawdzania kondycji sondy.
    • AccessViolationException jest obsługiwana.

    W przypadku AccessViolationException wystąpienia FailureStatus element jest zwracany z parametrem HealthCheckResult , aby umożliwić użytkownikom skonfigurowanie stanu niepowodzenia kontroli kondycji.

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Extensions.Diagnostics.HealthChecks;
    
    namespace SampleApp
    {
        public class ExampleHealthCheck : IHealthCheck
        {
            private readonly string _data1;
            private readonly int? _data2;
    
            public ExampleHealthCheck(string data1, int? data2)
            {
                _data1 = data1 ?? throw new ArgumentNullException(nameof(data1));
                _data2 = data2 ?? throw new ArgumentNullException(nameof(data2));
            }
    
            public async Task<HealthCheckResult> CheckHealthAsync(
                HealthCheckContext context, CancellationToken cancellationToken)
            {
                try
                {
                    return HealthCheckResult.Healthy();
                }
                catch (AccessViolationException ex)
                {
                    return new HealthCheckResult(
                        context.Registration.FailureStatus,
                        description: "An access violation occurred during the check.",
                        exception: ex,
                        data: null);
                }
            }
        }
    }
    
  2. Napisz metodę rozszerzenia z parametrami, które aplikacja zużywającą wywołuje w swojej Startup.Configure metodzie. W poniższym przykładzie przyjęto założenie, że podpis następującej metody sprawdzania kondycji:

    ExampleHealthCheck(string, string, int )
    

    Powyższy podpis wskazuje, że ExampleHealthCheck wymagane są dodatkowe dane do przetwarzania logiki sondy sprawdzania kondycji. Dane są udostępniane delegatowi użytemu do utworzenia wystąpienia kontroli kondycji po zarejestrowaniu sprawdzania kondycji za pomocą metody rozszerzenia. W poniższym przykładzie obiekt wywołujący określa opcjonalne:

    • nazwa kontroli kondycji (name). example_health_check Jeśli nullparametr jest używany.
    • punkt danych ciągu dla kontroli kondycji (data1).
    • Punkt danych liczby całkowitej dla kontroli kondycji (data2). 1 Jeśli nullparametr jest używany.
    • stan błędu (HealthStatus). Wartość domyślna to null. Jeśli nullparametr HealthStatus.Unhealthy jest zgłaszany jako stan niepowodzenia.
    • tagi (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));
        }
    }
    

Wydawca kontroli kondycji

Po dodaniu elementu IHealthCheckPublisher do kontenera usługi system sprawdzania kondycji okresowo wykonuje testy kondycji i wywołuje PublishAsync wynik. Jest to przydatne w scenariuszu systemu monitorowania kondycji opartego na wypychaniu, który oczekuje, że każdy proces będzie okresowo wywoływać system monitorowania w celu określenia kondycji.

Interfejs IHealthCheckPublisher ma jedną metodę:

Task PublishAsync(HealthReport report, CancellationToken cancellationToken);

HealthCheckPublisherOptions zezwalaj na ustawienie:

  • Delay: początkowe opóźnienie zastosowane po uruchomieniu aplikacji przed wykonaniem IHealthCheckPublisher wystąpień. Opóźnienie jest stosowane raz podczas uruchamiania i nie ma zastosowania do kolejnych iteracji. Wartość domyślna to pięć sekund.
  • Period: okres IHealthCheckPublisher wykonywania. Wartość domyślna to 30 sekund.
  • Predicate: Jeśli Predicate jest null (wartość domyślna), usługa wydawcy sprawdzania kondycji uruchamia wszystkie zarejestrowane testy kondycji. Aby uruchomić podzbiór kontroli kondycji, podaj funkcję, która filtruje zestaw testów. Predykat jest obliczany w każdym okresie.
  • Timeout: limit czasu wykonywania kontroli kondycji dla wszystkich IHealthCheckPublisher wystąpień. Użyj polecenia InfiniteTimeSpan , aby wykonać bez limitu czasu. Wartość domyślna to 30 sekund.

W przykładowej aplikacji ReadinessPublisher jest implementacją IHealthCheckPublisher . Stan kontroli kondycji jest rejestrowany dla każdego sprawdzenia na poziomie dziennika:

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

W przykładzie StartupHostedService przykładowej aplikacji LivenessProbeStartup test gotowości ma dwa sekundy opóźnienia uruchamiania i uruchamia sprawdzanie co 30 sekund. Aby aktywować implementacjęIHealthCheckPublisher, przykład rejestruje ReadinessPublisher się jako usługa pojedyncza w kontenerze wstrzykiwania zależności (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>();

Uwaga

AspNetCore.Diagnostics.HealthChecks zawiera wydawców dla kilku systemów, w tym usługi Application Insights.

AspNetCore.Diagnostics.HealthChecks firma Microsoft nie jest obsługiwana ani obsługiwana.

Ograniczanie kontroli kondycji za pomocą polecenia MapWhen

Użyj polecenia MapWhen , aby warunkowo rozgałęzić potok żądania dla punktów końcowych sprawdzania kondycji.

W poniższym przykładzie potok żądania jest odgałęzieny w MapWhen celu aktywowania oprogramowania pośredniczącego sprawdzania kondycji, jeśli żądanie GET zostanie odebrane dla punktu końcowego api/HealthCheck :

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

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

Aby uzyskać więcej informacji, zobacz Oprogramowanie pośredniczące ASP.NET Core.

ASP.NET Core oferuje oprogramowanie pośredniczące kontroli kondycji i biblioteki do raportowania kondycji składników infrastruktury aplikacji.

Testy kondycji są udostępniane przez aplikację jako punkty końcowe HTTP. Punkty końcowe kontroli kondycji można skonfigurować dla różnych scenariuszy monitorowania w czasie rzeczywistym:

  • Sondy kondycji mogą być używane przez koordynatorów kontenerów i moduły równoważenia obciążenia w celu sprawdzenia stanu aplikacji. Na przykład orkiestrator kontenerów może reagować na niepowodzenie sprawdzania kondycji, zatrzymując wdrożenie stopniowe lub ponownie uruchamiając kontener. Moduł równoważenia obciążenia może reagować na aplikację w złej kondycji, rozsyłając ruch z dala od wystąpienia w dobrej kondycji.
  • Użycie pamięci, dysku i innych zasobów serwera fizycznego można monitorować pod kątem stanu dobrej kondycji.
  • Testy kondycji mogą testować zależności aplikacji, takie jak bazy danych i zewnętrzne punkty końcowe usługi, w celu potwierdzenia dostępności i normalnego działania.

Testy kondycji są zwykle używane z zewnętrzną usługą monitorowania lub koordynatorem kontenerów w celu sprawdzenia stanu aplikacji. Przed dodaniem kontroli kondycji do aplikacji zdecyduj, który system monitorowania ma być używany. System monitorowania określa typy kontroli kondycji do utworzenia i sposobu konfigurowania ich punktów końcowych.

Podstawowa sonda kondycji

W przypadku wielu aplikacji podstawowa konfiguracja sondy kondycji, która zgłasza dostępność aplikacji do przetwarzania żądań (żywości) jest wystarczająca do odnalezienia stanu aplikacji.

Podstawowa konfiguracja rejestruje usługi sprawdzania kondycji i wywołuje oprogramowanie pośredniczące kontroli kondycji, aby odpowiedzieć w punkcie końcowym adresu URL z odpowiedzią na kondycję. Domyślnie żadne konkretne kontrole kondycji nie są rejestrowane w celu przetestowania żadnej konkretnej zależności lub podsystemu. Aplikacja jest uważana za w dobrej kondycji, jeśli może odpowiadać pod adresem URL punktu końcowego kondycji. Domyślny składnik zapisywania odpowiedzi zapisuje HealthStatus jako odpowiedź w postaci zwykłego tekstu na klienta. Parametr HealthStatus to HealthStatus.Healthy, HealthStatus.Degradedlub HealthStatus.Unhealthy.

Zarejestruj usługi sprawdzania kondycji za pomocą AddHealthChecks polecenia w programie Program.cs. Utwórz punkt końcowy kontroli kondycji, wywołując polecenie MapHealthChecks.

Poniższy przykład tworzy punkt końcowy kontroli kondycji w witrynie /healthz:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHealthChecks();

var app = builder.Build();

app.MapHealthChecks("/healthz");

app.Run();

Docker HEALTHCHECK

Platforma Docker oferuje wbudowaną HEALTHCHECK dyrektywę, która może służyć do sprawdzania stanu aplikacji korzystającej z podstawowej konfiguracji kontroli kondycji:

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

W poprzednim przykładzie użyto curl metody , aby wysłać żądanie HTTP do punktu końcowego sprawdzania kondycji pod adresem /healthz. curl nie jest uwzględniana w obrazach kontenerów systemu Linux platformy .NET, ale można ją dodać, instalując wymagany pakiet w pliku Dockerfile. Kontenery korzystające z obrazów opartych na systemie Alpine Linux mogą używać elementów dołączonych wget curlzamiast programu .

Tworzenie kontroli kondycji

Testy kondycji są tworzone przez zaimplementowanie interfejsu IHealthCheck . Metoda CheckHealthAsync zwraca wartość HealthCheckResult , która wskazuje kondycję jako Healthy, Degradedlub Unhealthy. Wynik jest zapisywany jako odpowiedź w postaci zwykłego tekstu z konfigurowalnym kodem stanu. Konfiguracja została opisana w sekcji Opcje sprawdzania kondycji. HealthCheckResult może również zwracać opcjonalne pary klucz-wartość.

W poniższym przykładzie pokazano układ kontroli kondycji:

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 kontroli kondycji jest umieszczana w metodzie CheckHealthAsync . W poprzednim przykładzie ustawiono fikcyjną zmienną , isHealthyna truewartość . Jeśli wartość parametru isHealthy jest ustawiona na falsewartość , HealthCheckRegistration.FailureStatus zwracany jest stan.

Jeśli CheckHealthAsync podczas sprawdzania zostanie zgłoszony wyjątek, zostanie zwrócony nowy HealthReportEntry element z ustawioną HealthReportEntry.Status wartością FailureStatus. Ten stan jest definiowany przez AddCheck (zobacz sekcję Rejestrowanie usług sprawdzania kondycji) i zawiera wyjątek wewnętrzny, który spowodował niepowodzenie sprawdzania. Parametr Description jest ustawiony na komunikat wyjątku.

Rejestrowanie usług kontroli kondycji

Aby zarejestrować usługę sprawdzania kondycji, wywołaj metodę w pliku AddCheck Program.cs:

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

Przeciążenie AddCheck pokazane w poniższym przykładzie ustawia stan błędu (HealthStatus) w celu raportowania, gdy kontrola kondycji zgłasza błąd. Jeśli stan niepowodzenia jest ustawiony na null (wartość domyślna), HealthStatus.Unhealthy jest zgłaszany. To przeciążenie jest przydatnym scenariuszem dla autorów bibliotek, w którym stan awarii wskazywany przez bibliotekę jest wymuszany przez aplikację, gdy wystąpi błąd sprawdzania kondycji, jeśli implementacja kontroli kondycji honoruje ustawienie.

Tagi mogą służyć do filtrowania kontroli kondycji. Tagi są opisane w sekcji Filtrowanie kontroli kondycji.

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

AddCheck może również wykonać funkcję lambda. W poniższym przykładzie sprawdzanie kondycji zawsze zwraca wynik w dobrej kondycji:

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

Wywołaj metodę AddTypeActivatedCheck , aby przekazać argumenty do implementacji kontroli kondycji. W poniższym przykładzie kontrola kondycji aktywowana typem akceptuje liczbę całkowitą i ciąg w konstruktorze:

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

Aby zarejestrować poprzednią kontrolę kondycji, wywołaj metodę AddTypeActivatedCheck za pomocą liczby całkowitej i ciągu przekazanego jako argumenty:

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

Używanie routingu sprawdzania kondycji

W Program.cspliku wywołaj MapHealthChecks konstruktora punktu końcowego przy użyciu adresu URL punktu końcowego lub ścieżki względnej:

app.MapHealthChecks("/healthz");

Wymagaj hosta

Wywołaj metodę RequireHost , aby określić co najmniej jeden dozwolony host dla punktu końcowego kontroli kondycji. Hosty powinny być unicode, a nie punycode i mogą zawierać port. Jeśli kolekcja nie zostanie dostarczona, zostanie zaakceptowany żaden host:

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

Aby ograniczyć punkt końcowy kontroli kondycji do odpowiadania tylko na określonym porcie, określ port w wywołaniu metody RequireHost. Takie podejście jest zwykle używane w środowisku kontenera do uwidaczniania portu na potrzeby usług monitorowania:

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

Ostrzeżenie

Interfejs API, który opiera się na nagłówku hosta, takim jak HttpRequest.Host i RequireHost, podlega potencjalnemu fałszowaniu przez klientów.

Aby zapobiec fałszowaniu hostów i portów, użyj jednej z następujących metod:

Aby zapobiec fałszowaniu portu przez nieautoryzowanych klientów, wywołaj metodę RequireAuthorization:

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

Aby uzyskać więcej informacji, zobacz Dopasowywanie hostów w trasach za pomocą elementu RequireHost.

Wymagaj autoryzacji

Wywołaj polecenie RequireAuthorization , aby uruchomić oprogramowanie pośredniczące autoryzacji w punkcie końcowym żądania sprawdzania kondycji. Przeciążenie RequireAuthorization akceptuje co najmniej jedną zasady autoryzacji. Jeśli nie podano zasad, są używane domyślne zasady autoryzacji:

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

Włączanie żądań Cross-Origin (CORS)

Mimo że ręczne uruchamianie kontroli kondycji z przeglądarki nie jest typowym scenariuszem, oprogramowanie pośredniczące CORS można włączyć przez wywołanie RequireCors punktów końcowych kontroli kondycji. Przeciążenie RequireCors akceptuje delegata konstruktora zasad CORS (CorsPolicyBuilder) lub nazwę zasad. Aby uzyskać więcej informacji, zobacz Włączanie żądań między źródłami (CORS) w ASP.NET Core.

Opcje kontroli kondycji

HealthCheckOptions umożliwia dostosowanie zachowania kontroli kondycji:

Filtrowanie kontroli kondycji

Domyślnie oprogramowanie pośredniczące sprawdzania kondycji uruchamia wszystkie zarejestrowane kontrole kondycji. Aby uruchomić podzbiór kontroli kondycji, podaj funkcję, która zwraca wartość logiczną do Predicate opcji.

Poniższy przykład filtruje testy kondycji tak, aby tylko te oznaczone przebiegiem sample :

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

Dostosowywanie kodu stanu HTTP

Służy ResultStatusCodes do dostosowywania mapowania stanu kondycji na kody stanu HTTP. Następujące StatusCodes przypisania są wartościami domyślnymi używanymi przez oprogramowanie pośredniczące. Zmień wartości kodu stanu, aby spełnić wymagania:

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

Pomijanie nagłówków pamięci podręcznej

AllowCachingResponses określa, czy oprogramowanie pośredniczące kontroli kondycji dodaje nagłówki HTTP do odpowiedzi sondy, aby zapobiec buforowaniu odpowiedzi. Jeśli wartość to false (wartość domyślna), oprogramowanie pośredniczące ustawia lub zastępuje Cache-Controlnagłówki , Expiresi Pragma , aby zapobiec buforowaniu odpowiedzi. Jeśli wartość to true, oprogramowanie pośredniczące nie modyfikuje nagłówków pamięci podręcznej odpowiedzi:

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

Dostosowywanie danych wyjściowych

Aby dostosować dane wyjściowe raportu kontroli kondycji, ustaw HealthCheckOptions.ResponseWriter właściwość na delegata, który zapisuje odpowiedź:

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

Domyślny delegat zapisuje minimalną odpowiedź w postaci zwykłego tekstu z wartością HealthReport.Statusciągu . Poniższy delegat niestandardowy zwraca niestandardową odpowiedź JSON przy użyciu polecenia 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()));
}

Interfejs API sprawdzania kondycji nie zapewnia wbudowanej obsługi złożonych formatów zwracanych JSON, ponieważ format jest specyficzny dla wybranego systemu monitorowania. Dostosuj odpowiedź w poprzednich przykładach zgodnie z potrzebami. Aby uzyskać więcej informacji na temat serializacji JSON za pomocą System.Text.Jsonprogramu , zobacz Jak serializować i deserializować kod JSON na platformie .NET.

Sonda bazy danych

Kontrola kondycji może określić zapytanie bazy danych do uruchomienia jako test logiczny, aby wskazać, czy baza danych odpowiada normalnie.

AspNetCore.Diagnostics.HealthChecks, biblioteka sprawdzania kondycji dla aplikacji ASP.NET Core zawiera kontrolę kondycji uruchamianą względem bazy danych programu SQL Server. AspNetCore.Diagnostics.HealthChecksSELECT 1 Wykonuje zapytanie względem bazy danych, aby potwierdzić, że połączenie z bazą danych jest w dobrej kondycji.

Ostrzeżenie

Podczas sprawdzania połączenia bazy danych z zapytaniem wybierz zapytanie, które szybko zwraca. Podejście do zapytania powoduje przeciążenie bazy danych i obniżenie wydajności. W większości przypadków uruchomienie zapytania testowego nie jest konieczne. Wystarczy nawiązać pomyślne połączenie z bazą danych. Jeśli okaże się, że konieczne jest uruchomienie zapytania, wybierz proste zapytanie SELECT, takie jak SELECT 1.

Aby użyć tej kontroli kondycji programu SQL Server, dołącz odwołanie do AspNetCore.HealthChecks.SqlServer pakietu NuGet. Poniższy przykład rejestruje kontrolę kondycji programu SQL Server:

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

Uwaga

AspNetCore.Diagnostics.HealthChecks firma Microsoft nie jest obsługiwana ani obsługiwana.

Sonda DbContext platformy Entity Framework Core

Sprawdzanie DbContext potwierdza, że aplikacja może komunikować się z bazą danych skonfigurowaną dla elementu EF CoreDbContext. Sprawdzanie DbContext jest obsługiwane w aplikacjach, które:

AddDbContextCheck rejestruje kontrolę kondycji dla elementu DbContext. Element DbContext jest dostarczany do metody jako TContext. Przeciążenie jest dostępne do skonfigurowania stanu niepowodzenia, tagów i niestandardowego zapytania testowego.

Domyślnie:

  • Wywołania DbContextHealthCheck EF CoreCanConnectAsync metody . Możesz dostosować operację uruchamianą podczas sprawdzania kondycji przy użyciu AddDbContextCheck przeciążeń metod.
  • Nazwa sprawdzania kondycji to nazwa TContext typu.

Poniższy przykład rejestruje element DbContext i skojarzony element DbContextHealthCheck:

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

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

Oddzielne sondy gotowości i aktualności

W niektórych scenariuszach hostingu para kontroli kondycji służy do rozróżniania dwóch stanów aplikacji:

  • Gotowość wskazuje, czy aplikacja działa normalnie, ale nie jest gotowa do odbierania żądań.
  • Liveness wskazuje, czy aplikacja uległa awarii i musi zostać ponownie uruchomiona.

Rozważmy następujący przykład: Aplikacja musi pobrać duży plik konfiguracji, zanim będzie gotowa do przetwarzania żądań. Nie chcemy, aby aplikacja została ponownie uruchomiona, jeśli początkowe pobieranie nie powiedzie się, ponieważ aplikacja może ponowić próbę pobrania pliku kilka razy. Używamy sondy liveness do opisania aktualności procesu, nie są uruchamiane żadne inne testy. Chcemy również uniemożliwić wysyłanie żądań do aplikacji przed pomyślnym pobraniem pliku konfiguracji. Używamy sondy gotowości, aby wskazać stan "nie jest gotowy", dopóki pobieranie nie powiedzie się, a aplikacja będzie gotowa do odbierania żądań.

Następujące zadanie w tle symuluje proces uruchamiania, który trwa około 15 sekund. Po zakończeniu zadania zadanie ustawia StartupHealthCheck.StartupCompleted właściwość 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;
    }
}

Raportuje StartupHealthCheck ukończenie długotrwałego zadania uruchamiania i uwidacznia StartupCompleted właściwość ustawianą przez usługę w tle:

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 kondycji jest zarejestrowana AddCheck razem Program.cs z hostowaną usługą. Ponieważ hostowana usługa musi ustawić właściwość w kontroli kondycji, sprawdzanie kondycji jest również zarejestrowane w kontenerze usługi jako pojedynczy:

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

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

Aby utworzyć dwa różne punkty końcowe kontroli kondycji, wywołaj dwa MapHealthChecks razy:

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

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

W poprzednim przykładzie są tworzone następujące punkty końcowe sprawdzania kondycji:

  • /healthz/ready w celu sprawdzenia gotowości. Sprawdzanie gotowości filtruje kontrole kondycji do tych oznaczonych tagiem ready.
  • /healthz/live w celu sprawdzenia aktualności. Sprawdzanie aktualności filtruje wszystkie kontrole kondycji, wracając false do delegata HealthCheckOptions.Predicate . Aby uzyskać więcej informacji na temat filtrowania kontroli kondycji, zobacz Filtrowanie kontroli kondycji w tym artykule.

Przed ukończeniem zadania uruchamiania /healthz/ready punkt końcowy zgłasza Unhealthy stan. Po zakończeniu zadania uruchamiania ten punkt końcowy zgłasza Healthy stan. Punkt /healthz/live końcowy wyklucza wszystkie kontrole i zgłasza Healthy stan wszystkich wywołań.

Przykład rozwiązania Kubernetes

Korzystanie z oddzielnych testów gotowości i dostępności jest przydatne w środowisku, takim jak Kubernetes. Na platformie Kubernetes aplikacja może być wymagana do wykonywania czasochłonnej pracy podczas uruchamiania przed zaakceptowaniem żądań, takich jak test dostępności bazowej bazy danych. Użycie oddzielnych kontroli umożliwia orkiestratorowi rozróżnienie, czy aplikacja działa, ale nie jest jeszcze gotowa, czy nie można uruchomić aplikacji. Aby uzyskać więcej informacji na temat sond gotowości i aktualności na platformie Kubernetes, zobacz Konfigurowanie sondy kondycji i gotowości w dokumentacji platformy Kubernetes.

W poniższym przykładzie pokazano konfigurację sondy gotowości platformy 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

Rozpowszechnianie biblioteki kontroli kondycji

Aby rozpowszechnić kontrolę kondycji jako bibliotekę:

  1. Napisz kontrolę kondycji, która implementuje IHealthCheck interfejs jako klasę autonomiczną. Klasa może polegać na iniekcji zależności (DI), aktywacji typu i nazwanych opcjach uzyskiwania dostępu do danych konfiguracji.

  2. Napisz metodę rozszerzenia z parametrami, które aplikacja zużywającą wywołuje w swojej Program.cs metodzie. Rozważmy następujący przykładowy sprawdzanie kondycji, który akceptuje arg1 parametry konstruktora i arg2 jako parametry konstruktora:

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

    Powyższy podpis wskazuje, że kontrola kondycji wymaga niestandardowych danych do przetwarzania logiki sondy sprawdzania kondycji. Dane są udostępniane delegatowi użytemu do utworzenia wystąpienia kontroli kondycji po zarejestrowaniu sprawdzania kondycji za pomocą metody rozszerzenia. W poniższym przykładzie obiekt wywołujący określa:

    • arg1: punkt danych liczby całkowitej dla sprawdzania kondycji.
    • arg2: argument ciągu dla sprawdzania kondycji.
    • name: opcjonalna nazwa sprawdzania kondycji. Jeśli nullzostanie użyta wartość domyślna.
    • failureStatus: opcjonalny HealthStatuselement , który jest zgłaszany dla stanu błędu. HealthStatus.Unhealthy Jeśli nullparametr jest używany.
    • tags: opcjonalna IEnumerable<string> kolekcja tagów.
    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));
        }
    }
    

Wydawca kontroli kondycji

Po dodaniu elementu IHealthCheckPublisher do kontenera usługi system sprawdzania kondycji okresowo wykonuje testy kondycji i wywołuje PublishAsync wynik. Ten proces jest przydatny w scenariuszu systemu monitorowania kondycji opartego na wypychaniach, który oczekuje, że każdy proces będzie okresowo wywoływać system monitorowania w celu określenia kondycji.

HealthCheckPublisherOptions umożliwia ustawienie następujących opcji:

  • Delay: początkowe opóźnienie zastosowane po uruchomieniu aplikacji przed wykonaniem IHealthCheckPublisher wystąpień. Opóźnienie jest stosowane raz podczas uruchamiania i nie ma zastosowania do późniejszych iteracji. Wartość domyślna to pięć sekund.
  • Period: okres IHealthCheckPublisher wykonywania. Wartość domyślna to 30 sekund.
  • Predicate: Jeśli Predicate jest null (wartość domyślna), usługa wydawcy sprawdzania kondycji uruchamia wszystkie zarejestrowane testy kondycji. Aby uruchomić podzbiór kontroli kondycji, podaj funkcję, która filtruje zestaw testów. Predykat jest obliczany w każdym okresie.
  • Timeout: limit czasu wykonywania kontroli kondycji dla wszystkich IHealthCheckPublisher wystąpień. Użyj polecenia InfiniteTimeSpan , aby wykonać bez limitu czasu. Wartość domyślna to 30 sekund.

W poniższym przykładzie pokazano układ wydawcy kondycji:

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

        return Task.CompletedTask;
    }
}

Klasa HealthCheckPublisherOptions udostępnia właściwości służące do konfigurowania zachowania wydawcy kontroli kondycji.

W poniższym przykładzie wydawca kontroli kondycji jest rejestrowany jako pojedynczy użytkownik i konfiguruje HealthCheckPublisherOptionselement :

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

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

Uwaga

AspNetCore.Diagnostics.HealthChecks zawiera wydawców dla kilku systemów, w tym usługi Application Insights.

AspNetCore.Diagnostics.HealthChecks firma Microsoft nie jest obsługiwana ani obsługiwana.

Wstrzykiwanie zależności i kontrole kondycji

Można użyć iniekcji zależności, aby użyć wystąpienia określonego Type wewnątrz klasy Kontroli kondycji. Wstrzykiwanie zależności może być przydatne do wstrzykiwania opcji lub konfiguracji globalnej do kontroli kondycji. Używanie wstrzykiwania zależności nie jest typowym scenariuszem konfigurowania kontroli kondycji. Zwykle każda kontrola kondycji jest dość specyficzna dla rzeczywistego testu i jest konfigurowana przy użyciu IHealthChecksBuilder metod rozszerzeń.

W poniższym przykładzie pokazano przykładową kontrolę kondycji, która pobiera obiekt konfiguracji za pośrednictwem iniekcji zależności:

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

Element SampleHealthCheckWithDiConfig i sprawdzanie kondycji należy dodać do kontenera usługi :

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

Istnieją dwa sposoby udostępniania kontroli kondycji obiektom wywołującym:

  • UseHealthChecks rejestruje oprogramowanie pośredniczące do obsługi żądań kontroli kondycji w potoku oprogramowania pośredniczącego.
  • MapHealthChecks rejestruje punkt końcowy kontroli kondycji. Punkt końcowy jest zgodny i wykonywany wraz z innymi punktami końcowymi w aplikacji.

Zaletą używania MapHealthChecks funkcji over UseHealthChecks jest możliwość używania oprogramowania pośredniczącego obsługującego punkty końcowe, takiego jak autoryzacja, oraz większej precyzyjnej kontroli nad pasującymi zasadami. Główną zaletą używania UseHealthChecks funkcji over MapHealthChecks jest kontrolowanie dokładnie tego, gdzie testy kondycji są uruchamiane w potoku oprogramowania pośredniczącego.

UseHealthChecks:

  • Przerywa potok, gdy żądanie jest zgodne z punktem końcowym sprawdzania kondycji. Zwarcie jest często pożądane, ponieważ pozwala uniknąć niepotrzebnej pracy, takiej jak rejestrowanie i inne oprogramowanie pośredniczące.
  • Służy głównie do konfigurowania oprogramowania pośredniczącego kontroli kondycji w potoku.
  • Może być zgodna z dowolną ścieżką na porcie lub pustą null PathString. Umożliwia przeprowadzenie kontroli kondycji dla dowolnego żądania skierowanego do określonego portu.
  • Kod źródłowy

MapHealthChecks Pozwala:

  • Mapowanie określonych tras lub punktów końcowych na potrzeby kontroli kondycji.
  • Dostosowanie adresu URL lub ścieżki, w której jest dostępny punkt końcowy sprawdzania kondycji.
  • Mapowanie wielu punktów końcowych kontroli kondycji z różnymi trasami lub konfiguracjami. Obsługa wielu punktów końcowych:
    • Włącza oddzielne punkty końcowe dla różnych typów kontroli kondycji lub składników.
    • Służy do rozróżniania różnych aspektów kondycji aplikacji lub stosowania określonych konfiguracji do podzbiorów kontroli kondycji.
  • Kod źródłowy

Dodatkowe zasoby

Uwaga

Ten artykuł został częściowo utworzony z pomocą sztucznej inteligencji. Przed opublikowaniem autor przejrzał i poprawił zawartość zgodnie z potrzebą. Zapoznaj się z naszymi zasadami korzystania z zawartości generowanej za pośrednictwem AI w usłudze Microsoft Learn.