Monitorování stavu

Tip

Tento obsah je výňatek z eBooku, architektury mikroslužeb .NET pro kontejnerizované aplikace .NET, které jsou k dispozici na .NET Docs nebo jako zdarma ke stažení PDF, které lze číst offline.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

Monitorování stavu může umožňovat téměř v reálném čase informace o stavu kontejnerů a mikroslužeb. Monitorování stavu je důležité pro několik aspektů provozních mikroslužeb a je zvlášť důležité, když orchestrátory provádějí částečné upgrady aplikací ve fázích, jak je vysvětleno později.

Aplikace založené na mikroslužbách často používají prezenční signály nebo kontroly stavu, aby jejich monitory výkonu, plánovače a orchestrátory mohly sledovat velké množství služeb. Pokud služby nemůžou posílat nějaký signál "Jsem naživu", ať už na vyžádání, nebo podle plánu, může vaše aplikace čelit rizikům při nasazování aktualizací, nebo může pouze detekovat chyby příliš pozdě a nemůže zastavit kaskádové selhání, které můžou skončit v hlavních výpadkech.

V typickém modelu služby odesílají sestavy o svém stavu a informace se agregují, aby poskytovaly celkový přehled o stavu vaší aplikace. Pokud používáte orchestrátor, můžete clusteru orchestrátoru poskytnout informace o stavu, aby cluster mohl odpovídajícím způsobem fungovat. Pokud investujete do vysoce kvalitního hlášení o stavu, které je přizpůsobené pro vaši aplikaci, můžete snadněji detekovat a opravit problémy pro spuštěnou aplikaci.

Implementace kontrol stavu ve službách ASP.NET Core

Při vývoji mikroslužby ASP.NET Core nebo webové aplikace můžete použít integrovanou funkci kontrol stavu, která byla vydána v ASP .NET Core 2.2 (Microsoft.Extensions.Diagnostics.HealthChecks). Stejně jako mnoho funkcí ASP.NET Core jsou kontroly stavu součástí sady služeb a middlewaru.

Služby kontroly stavu a middleware se snadno používají a poskytují funkce, které umožňují ověřit, jestli nějaký externí prostředek potřebný pro vaši aplikaci (například databáze SQL Serveru nebo vzdálené rozhraní API) funguje správně. Když použijete tuto funkci, můžete se také rozhodnout, co znamená, že prostředek je v pořádku, jak je vysvětleno později.

Pokud chcete tuto funkci efektivně používat, musíte nejprve nakonfigurovat služby v mikroslužbách. Zadruhé potřebujete front-endovou aplikaci, která se dotazuje na sestavy stavu. Tato front-endová aplikace může být vlastní aplikace pro vytváření sestav, nebo se může jednat o orchestrátor, který může odpovídajícím způsobem reagovat na stavové stavy.

Použití funkce HealthChecks v back-endových ASP.NET mikroslužeb

V této části se dozvíte, jak implementovat funkci HealthChecks v ukázkové aplikaci webového rozhraní API pro ASP.NET Core 8.0 při použití balíčku Microsoft.Extensions.Diagnostics.HealthChecks . Implementace této funkce ve velkých mikroslužbách, jako je eShopOnContainers, je vysvětlena v další části.

Abyste mohli začít, musíte definovat, co představuje stav v pořádku pro každou mikroslužbu. V ukázkové aplikaci definujeme, že mikroslužba je v pořádku, pokud je její rozhraní API přístupné prostřednictvím protokolu HTTP a je k dispozici také související databáze SQL Serveru.

V .NET 8 s integrovanými rozhraními API můžete nakonfigurovat služby, přidat kontrolu stavu pro mikroslužbu a její závislé databáze SQL Serveru tímto způsobem:

// Program.cs from .NET 8 Web API sample

//...
// Registers required services for health checks
builder.Services.AddHealthChecks()
    // Add a health check for a SQL Server database
    .AddCheck(
        "OrderingDB-check",
        new SqlConnectionHealthCheck(builder.Configuration["ConnectionString"]),
        HealthStatus.Unhealthy,
        new string[] { "orderingdb" });

V předchozím kódu services.AddHealthChecks() metoda nakonfiguruje základní kontrolu HTTP, která vrátí stavový kód 200 s "V pořádku". Metoda rozšíření dále konfiguruje vlastníSqlConnectionHealthCheck, AddCheck() která kontroluje stav související služby SQL Database.

Metoda AddCheck() přidá novou kontrolu stavu se zadaným názvem a implementací typu IHealthCheck. Pomocí metody AddCheck můžete přidat více kontrol stavu, takže mikroslužba nebude poskytovat stav v pořádku, dokud nebudou všechny kontroly v pořádku.

SqlConnectionHealthCheckje vlastní třída, která implementuje IHealthCheck, který přebírá připojovací řetězec jako parametr konstruktoru a spustí jednoduchý dotaz, který zkontroluje, zda připojení k databázi SQL je úspěšné. HealthCheckResult.Healthy() Vrátí, pokud byl dotaz úspěšně proveden, a s skutečnou FailureStatus výjimkou, když selže.

// Sample SQL Connection Health Check
public class SqlConnectionHealthCheck : IHealthCheck
{
    private const string DefaultTestQuery = "Select 1";

    public string ConnectionString { get; }

    public string TestQuery { get; }

    public SqlConnectionHealthCheck(string connectionString)
        : this(connectionString, testQuery: DefaultTestQuery)
    {
    }

    public SqlConnectionHealthCheck(string connectionString, string testQuery)
    {
        ConnectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
        TestQuery = testQuery;
    }

    public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken))
    {
        using (var connection = new SqlConnection(ConnectionString))
        {
            try
            {
                await connection.OpenAsync(cancellationToken);

                if (TestQuery != null)
                {
                    var command = connection.CreateCommand();
                    command.CommandText = TestQuery;

                    await command.ExecuteNonQueryAsync(cancellationToken);
                }
            }
            catch (DbException ex)
            {
                return new HealthCheckResult(status: context.Registration.FailureStatus, exception: ex);
            }
        }

        return HealthCheckResult.Healthy();
    }
}

Všimněte si, Select 1 že v předchozím kódu je dotaz použitý ke kontrole stavu databáze. Pokud chcete monitorovat dostupnost mikroslužeb, orchestrátory, jako je Kubernetes, pravidelně provádějí kontroly stavu odesláním požadavků na testování mikroslužeb. Je důležité zajistit efektivní databázové dotazy, aby tyto operace byly rychlé a nezpůsobily vyšší využití prostředků.

Nakonec přidejte middleware, který reaguje na cestu /hcurl:

// Program.cs from .NET 8 Web Api sample

app.MapHealthChecks("/hc");

Při vyvolání koncového bodu <yourmicroservice>/hc se spustí všechny kontroly stavu nakonfigurované v AddHealthChecks() metodě ve třídě Startup a zobrazí výsledek.

Implementace HealthChecks v eShopOnContainers

Mikroslužby v eShopOnContainers spoléhají na několik služeb, které provádějí svou úlohu. Například Catalog.API mikroslužba z eShopOnContainers závisí na mnoha službách, jako je Azure Blob Storage, SQL Server a RabbitMQ. Proto má pomocí této metody přidaných AddCheck() několik kontrol stavu. Pro každou závislou službu bude potřeba přidat vlastní IHealthCheck implementaci, která definuje příslušný stav.

Open source projekt AspNetCore.Diagnostics.HealthChecks řeší tento problém tím, že poskytuje vlastní implementace kontroly stavu pro každou z těchto podnikových služeb, které jsou postavené na rozhraní .NET 8. Každá kontrola stavu je k dispozici jako samostatný balíček NuGet, který lze snadno přidat do projektu. eShopOnContainers je používá ve všech svých mikroslužbách značně.

Například v Catalog.API mikroslužbě byly přidány následující balíčky NuGet:

Screenshot of the AspNetCore.Diagnostics.HealthChecks NuGet packages.

Obrázek 8-7 Vlastní kontroly stavu implementované v catalog.API pomocí AspNetCore.Diagnostics.HealthChecks

V následujícím kódu se přidají implementace kontroly stavu pro každou závislou službu a pak se nakonfiguruje middleware:

// Extension method from Catalog.api microservice
//
public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration)
{
    var accountName = configuration.GetValue<string>("AzureStorageAccountName");
    var accountKey = configuration.GetValue<string>("AzureStorageAccountKey");

    var hcBuilder = services.AddHealthChecks();

    hcBuilder
        .AddSqlServer(
            configuration["ConnectionString"],
            name: "CatalogDB-check",
            tags: new string[] { "catalogdb" });

    if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey))
    {
        hcBuilder
            .AddAzureBlobStorage(
                $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net",
                name: "catalog-storage-check",
                tags: new string[] { "catalogstorage" });
    }
    if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
    {
        hcBuilder
            .AddAzureServiceBusTopic(
                configuration["EventBusConnection"],
                topicName: "eshop_event_bus",
                name: "catalog-servicebus-check",
                tags: new string[] { "servicebus" });
    }
    else
    {
        hcBuilder
            .AddRabbitMQ(
                $"amqp://{configuration["EventBusConnection"]}",
                name: "catalog-rabbitmqbus-check",
                tags: new string[] { "rabbitmqbus" });
    }

    return services;
}

Nakonec přidejte middleware HealthCheck pro naslouchání koncovému bodu /hc:

// HealthCheck middleware
app.UseHealthChecks("/hc", new HealthCheckOptions()
{
    Predicate = _ => true,
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});

Dotazování mikroslužeb na hlášení o stavu mikroslužeb

Pokud jste nakonfigurovali kontroly stavu, jak je popsáno v tomto článku a máte mikroslužbu spuštěnou v Dockeru, můžete přímo zkontrolovat, jestli je v prohlížeči v pořádku. Port kontejneru musíte publikovat v hostiteli Dockeru, abyste k němu měli přístup prostřednictvím externí IP adresy hostitele Dockeru nebo prostřednictvím host.docker.internal, jak je znázorněno na obrázku 8–8.

Screenshot of the JSON response returned by a health check.

Obrázek 8–8 Kontrola stavu jedné služby z prohlížeče

V tomto testu vidíte, že Catalog.API mikroslužba (spuštěná na portu 5101) je v pořádku a vrací stav HTTP 200 a informace o stavu ve formátu JSON. Služba také zkontrolovala stav závislosti databáze SQL Serveru a RabbitMQ, takže kontrola stavu hlásila, že je v pořádku.

Použití watchdogs

Watchdog je samostatná služba, která může sledovat stav a načítání napříč službami a hlásit stav mikroslužeb dotazováním pomocí HealthChecks dříve zavedené knihovny. To může pomoct zabránit chybám, které by nebyly zjištěny na základě zobrazení jedné služby. Watchdogs jsou také dobrým místem pro hostování kódu, který může provádět nápravné akce pro známé podmínky bez zásahu uživatele.

Ukázka eShopOnContainers obsahuje webovou stránku, která zobrazuje ukázkové sestavy kontroly stavu, jak je znázorněno na obrázku 8-9. Toto je nejjednodušší sledovací zařízení, které byste mohli mít, protože zobrazuje pouze stav mikroslužeb a webových aplikací v eShopOnContainers. Sledovací zařízení obvykle provádí akce, když detekuje stavy, které nejsou v pořádku.

AspNetCore.Diagnostics.HealthChecks naštěstí také poskytuje balíček NuGet AspNetCore.HealthChecks.UI, který lze použít k zobrazení výsledků kontroly stavu z nakonfigurovaných identifikátorů URI.

Screenshot of the Health Checks UI eShopOnContainers health statuses.

Obrázek 8-9 Ukázková sestava kontroly stavu v eShopOnContainers

Stručně řečeno, tato služba watchdog se dotazuje na koncový bod "/hc" každé mikroslužby. Tím se spustí všechny kontroly stavu definované v něm a v závislosti na všech těchto kontrolách vrátí celkový stav. HealthChecksUI se snadno používá s několika položkami konfigurace a dvěma řádky kódu, které je potřeba přidat do Startup.cs služby watchdog.

Ukázkový konfigurační soubor pro uživatelské rozhraní kontroly stavu:

// Configuration
{
  "HealthChecksUI": {
    "HealthChecks": [
      {
        "Name": "Ordering HTTP Check",
        "Uri": "http://host.docker.internal:5102/hc"
      },
      {
        "Name": "Ordering HTTP Background Check",
        "Uri": "http://host.docker.internal:5111/hc"
      },
      //...
    ]}
}

Program.cs soubor, který přidává HealthChecksUI:

// Program.cs from WebStatus(Watch Dog) service
//
// Registers required services for health checks
builder.Services.AddHealthChecksUI();
// build the app, register other middleware
app.UseHealthChecksUI(config => config.UIPath = "/hc-ui");

Kontroly stavu při používání orchestrátorů

Pokud chcete monitorovat dostupnost mikroslužeb, orchestrátory, jako je Kubernetes a Service Fabric, pravidelně provádějí kontroly stavu odesíláním požadavků na testování mikroslužeb. Když orchestrátor zjistí, že služba nebo kontejner není v pořádku, zastaví směrování požadavků na danou instanci. Obvykle také vytvoří novou instanci tohoto kontejneru.

Většina orchestrátorů může například použít kontroly stavu ke správě nasazení s nulovými výpadky. Pouze když se stav služby nebo kontejneru změní na v pořádku, orchestrátor začne směrovat provoz do služby nebo instancí kontejnerů.

Monitorování stavu je zvlášť důležité, když orchestrátor provádí upgrade aplikace. Některé orchestrátory (například Azure Service Fabric) aktualizují služby ve fázích, například můžou aktualizovat jednu pětinu plochy clusteru pro každý upgrade aplikace. Sada uzlů, které se upgradují současně, se označuje jako upgradovací doména. Po upgradu každé upgradované domény, která je dostupná uživatelům, musí tato doména upgradu před přechodem na další doménu upgradu předat kontroly stavu.

Dalším aspektem stavu služby je generování metrik ze služby. Jedná se o pokročilou funkci modelu stavu některých orchestrátorů, jako je Service Fabric. Metriky jsou důležité při použití orchestrátoru, protože se používají k vyrovnávání využití prostředků. Metriky můžou být také indikátorem stavu systému. Můžete mít například aplikaci, která má mnoho mikroslužeb, a každá instance hlásí metriku žádosti za sekundu (RPS). Pokud jedna služba používá více prostředků (paměť, procesor atd.) než jiná služba, orchestrátor může přesunout instance služby v clusteru, aby se pokusil zachovat i využití prostředků.

Všimněte si, že Azure Service Fabric poskytuje vlastní model Monitorování stavu, který je pokročilejší než jednoduché kontroly stavu.

Pokročilé monitorování: vizualizace, analýza a upozornění

Poslední částí monitorování je vizualizace streamu událostí, generování sestav o výkonu služby a upozorňování při zjištění problému. Pro tento aspekt monitorování můžete použít různá řešení.

Při vysvětlení aspNetCore.Diagnostics.HealthChecks můžete použít jednoduché vlastní aplikace zobrazující stav služeb, jako je vlastní stránka zobrazená. Nebo můžete použít pokročilejší nástroje, jako je Azure Monitor , k vyvolání upozornění na základě streamu událostí.

A konečně, pokud ukládáte všechny streamy událostí, můžete k vizualizaci dat použít Microsoft Power BI nebo jiná řešení, jako je Kibana nebo Splunk.

Další materiály