Czy Twój serwis jest zdrowy? Kontrole stanu w ASP.NET Core 6.0
Aby utrzymać ogólną stabilność i wydajność systemu w świecie mikrousług i rozproszonych systemów, kluczowe jest monitorowanie stanu zdrowia każdej usługi. ASP.NET Core 6.0 ma wbudowane wsparcie dla kontroli stanu, umożliwiając deweloperom łatwe jej wdrożenie w aplikacjach. W tym artykule pokażę Ci, jak implementować kontrole stanu w ASP.NET Core 6.0. Wykorzystamy w tym celu zarówno wbudowane funkcje, jak i biblioteki stron trzecich, np. AspNetCore.Diagnostics.HealthChecks.
Wymagania wstępne
Aby śledzić przykłady w tym artykule, niezbędne są:
- Podstawowa wiedza o .NET 6.0
- Edytor tekstu do pisania kodu (np. Visual Studio Code)
Pierwszy krok
Aby zacząć, utwórz nowy projekt ASP.NET Core 6.0 Web API. Możesz to zrobić, używając następującego polecenia:
dotnet new webapi -n HealthCheckExample -f net6.0
Następnie przejdź do folderu HealtCheckExample
i otwórz plik Program.cs
. Zacznij od dodania middleware do kontroli stanu do aplikacji.
Dodawanie middleware do kontroli stanu
Aby dodać middleware do kontroli stanu, musisz zarejestrować usługę AddHealthChecks
w metodzie ConfigureServices naszego pliku Program.cs
. Zaktualizuj metodę Main, aby zawierała następujący kod:
using var builder = WebApplication.CreateBuilder(args);
// Add Health Checks
builder.Services.AddHealthChecks();
var app = builder.Build();
// Add Health Check endpoint
app.MapHealthChecks("/health");
app.MapControllers();
app.Run();
W powyższym kodzie dodaliśmy usługę kontroli stanu, wywołując AddHealthChecks()
na właściwości Services buildera. Następnie utworzyliśmy punkt końcowy dla kontroli stanu pod ścieżką "/health"
, używając metody MapHealthChecks
.
Testowanie podstawowej kontroli stanu
Gdy masz już middleware kontroli stanu i punkt końcowy, możesz uruchomić aplikację i przetestować kontrolę stanu.
- Uruchom aplikację, używając polecenia:
dotnet run
- Przejdź do
<https://localhost:5001/health>
w swojej przeglądarce internetowej lub użyj narzędzia takiego jak Postman, aby wysłać żądanie HTTP GET do tego punktu końcowego. Gdy to zrobisz, powinna pojawić się następująca odpowiedź:
Healthy
Domyślna kontrola stanu wskazuje, że nasza aplikacja jest zdrowa. Jednak ta podstawowa kontrola stanu nie dostarcza zbyt wielu informacji o rzeczywistym stanie naszej aplikacji. Aby monitorować konkretne komponenty naszej aplikacji, warto więc dodać kilka niestandardowych kontroli stanu.
Dodawanie niestandardowych kontroli stanu
Wyobraź sobie, że Twoja aplikacja polega na bazie danych i kolejce komunikatów. Z pewnością chcesz monitorować stan zdrowia obu tych komponentów. Aby było to realne, możesz stworzyć niestandardowe klasy kontroli stanu implementujące interfejs IHealthCheck.
- Na początek stwórz niestandardową kontrolę stanu dla naszej bazy danych. Utwórz nowy plik o nazwie
DatabaseHealthCheck.cs
i dodaj do niego następujący kod:
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Diagnostics.HealthChecks;
public class DatabaseHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
// Replace with your actual database connection check logic
bool isHealthy = true;
if (isHealthy)
{
return Task.FromResult(HealthCheckResult.Healthy("Database is healthy"));
}
return Task.FromResult(HealthCheckResult.Unhealthy("Database is not healthy"));
}
}
- Następnie utwórz niestandardową kontrolę stanu dla naszej kolejki komunikatów. Utwórz nowy plik o nazwie
MessageQueueHealthCheck.cs
i dodaj do niego poniższy kod:
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Diagnostics.HealthChecks;
public class MessageQueueHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken =default)
{
// Replace with your actual message queue connection check logic
bool isHealthy = true;
if (isHealthy)
{
return Task.FromResult(HealthCheckResult.Healthy("Message queue is healthy"));
}
return Task.FromResult(HealthCheckResult.Unhealthy("Message queue is not healthy"));
}
}
- Po dodaniu niestandardowych kontroli stanu możesz zarejestrować je w metodzie
ConfigureServices
plikuProgram.cs
. Jak to zrobić? Zaktualizuj metodęMain
, aby zawierała taki kod:
using var builder = WebApplication.CreateBuilder(args);
// Add Health Checks and Custom Health Checks
builder.Services.AddHealthChecks()
.AddCheck<DatabaseHealthCheck>("Database")
.AddCheck<MessageQueueHealthCheck>("MessageQueue");
var app = builder.Build();
// Add Health Check endpoint
app.MapHealthChecks("/health");
app.MapControllers();
app.Run();
Gotowe – dodaliśmy niestandardowe kontrole stanu, wywołując metodę AddCheck i przekazując typ naszej kontroli stanu oraz nazwę dla niej.
Modyfikacja odpowiedzi punktu końcowego
Możesz zdefiniować niestandardową metodę do formatowania wyników kontroli stanu w formacie JSON.
- Aby było to możliwe, utwórz nowy plik o nazwie
CustomHealthCheckResponseWriter.cs
w katalogu swojego projektu. Jak to zrobić? Spójrz:
using System.Collections.Generic;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Diagnostics.HealthChecks;
public static class CustomHealthCheckResponseWriter
{
public static async Task WriteCustomHealthCheckResponse(HttpContext context, HealthReport report)
{
context.Response.ContentType = "application/json";
var healthCheckResults = new Dictionary<string, object>
{
{ "status", report.Status.ToString() },
{ "results", new Dictionary<string, object>() }
};
foreach (var entry in report.Entries)
{
var entryValues = new Dictionary<string, object>
{
{ "status", entry.Value.Status.ToString() },
{ "description", entry.Value.Description },
{ "duration", entry.Value.Duration.ToString() }
};
((Dictionary<string, object>)healthCheckResults["results"]).Add(entry.Key, entryValues);
}
await context.Response.WriteAsync(JsonSerializer.Serialize(healthCheckResults, new JsonSerializerOptions { WriteIndented = true }));
}
}
- Następnie zaktualizuj plik
Program.cs
, aby używał niestandardowego ResponseWriter z klasyCustomHealthCheckResponseWriter
:
// ...
var app = builder.Build();
// Add Health Check endpoints
app.MapHealthChecks("/health", new HealthCheckOptions
{
Predicate = _ => true,
ResponseWriter = CustomHealthCheckResponseWriter.WriteCustomHealthCheckResponse
});
// ...
app.Run();
- Uruchom ponownie aplikację i przejdź do https://localhost:5001/health w przeglądarce internetowej. Możesz też użyć narzędzia takiego jak Postman, aby wysłać żądanie HTTP GET do tego punktu końcowego.
Tym razem powinna pojawić się odpowiedź w formacie JSON zawierająca status każdej niestandardowej kontroli stanu. Zobacz:
{
"status": "Healthy",
"results": {
"Database": {
"status": "Healthy",
"description": "Database is healthy",
"duration": "00:00:00.0009610"
},
"MessageQueue": {
"status": "Healthy",
"description": "Message queue is healthy",
"duration": "00:00:00.0009615"
}
}
}
Korzystanie z bibliotek zewnętrznych
Jeśli chcesz rozszerzyć funkcjonalność kontroli stanu w Twojej aplikacji, możesz użyć bibliotek stron trzecich, np. AspNetCore.Diagnostics.HealthChecks
. Zapewnia ona dodatkowe implementacje kontroli stanu dla różnych komponentów takich jak m.in. bazy danych czy pamięci podręczne.
- Aby użyć tej biblioteki, najpierw dodaj odpowiednie pakiety NuGet do projektu. Przykład? Jeśli chcesz dodać kontrole stanu dla SQL Server i Redis, konieczne jest zainstalowanie następujących pakietów:
dotnet add package AspNetCore.HealthChecks.SqlServer
dotnet add package AspNetCore.HealthChecks.Redis
- Następnie zaktualizuj plik
Program.cs
, aby zawierał niezbędne instrukcje using i zarejestrował dodatkowe kontrole stanu. Jak to zrobić? Spójrz:
using HealthChecks.SqlServer;
using HealthChecks.Redis;
// ...
using var builder = WebApplication.CreateBuilder(args);
// Add Health Checks and Custom Health Checks
builder.Services.AddHealthChecks()
.AddCheck<DatabaseHealthCheck>("Database")
.AddCheck<MessageQueueHealthCheck>("MessageQueue")
.AddSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"), name: "SQL Server")
.AddRedis(builder.Configuration.GetConnectionString("Redis"), name: "Redis");
// ...
Gdy uruchomisz aplikację i przejdziesz do punktu końcowego kontroli stanu, zobaczysz dodatkowe kontrole stanu w odpowiedzi.
Dodawanie interfejsu użytkownika kontroli stanu
Kolejną przydatną funkcją dostarczaną przez bibliotekę AspNetCore.Diagnostics.HealthChecks
jest HealthCheck UI. Ten interfejs użytkownika pozwala na wizualizację stanu zdrowia Twoich usług w internetowym panelu kontrolnym. HealthCheck UI może agregować stan zdrowia wielu usług, co czyni go cennym narzędziem w architekturze mikrousług. Jak skonfigurować HeltCheck UI?
- Aby użyć HealthCheck UI, musisz zainstalować następujące pakiety NuGet:
dotnet add package AspNetCore.HealthChecks.UI
dotnet add package AspNetCore.HealthChecks.UI.Client
dotnet add package AspNetCore.HealthChecks.UI.InMemory.Storage
- Następnie zaktualizuj swój plik
Program.cs
i zarejestruj HealthCheck UI:
using HealthChecks.UI.Client;
// ...
builder.Services.AddHealthChecksUI(setupSettings: setup =>
{
setup.AddHealthCheckEndpoint("main", "/health");
})
.AddInMemoryStorage();
// ...
app.MapHealthChecks("/health", new HealthCheckOptions(){
Predicate = _ => true,
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
// ....
app.MapHealthChecksUI(options =>
{
options.UIPath = "/health-ui";
});
// ...
W powyższym kodzie dodaliśmy usługę HealthCheck UI, wywołując AddHealthChecksUI()
na właściwości Services buildera. Określiliśmy także użycie pamięci wewnętrznej do przechowywania historii kontroli stanu, co jest przydatne do celów rozwojowych. Co dalej?
- Uruchom ponownie aplikację i przejdź do https://localhost:5001/health-ui w przeglądarce internetowej. Powinien pojawić się panel HealthCheck UI wyświetlający stan zdrowia zarejestrowanych usług.
Podsumowanie
W tym artykule pokazałem, jak wdrożyć kontrole stanu w ASP.NET Core 6.0, korzystając zarówno ze wbudowanych funkcji, jak i bibliotek stron trzecich (np. AspNetCore.Diagnostics.HealthChecks
). Dodając kontrole stanu do swojej aplikacji, możesz lepiej monitorować jej komponenty i zapewnić, że pozostanie stabilna i wydajna.
Źródła
https://learn.microsoft.com/pl-pl/aspnet/core/host-and-deploy/health-checks?view=aspnetcore-6.0 https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks