Controllare lo stato di un servizio gRPC in ASP.NET Core tramite Health Check

di Morgan Pizzini, in ASP.NET Core,

In un articolo precedente (https://www.aspitalia.com/articoli/asp.net-core5/grpc/usare-grpc-infrastruttura-nostri-servizi-web.aspx) abbiamo introdotto il protocollo gRPC: una tecnologia di comunicazione che si contrappone al mondo Web API, utilizzando serializzazione binaria e contratti definiti in file Protobuf.

Così come per le Web API, anche per l'interrogazione gRPC potremmo voler sapere se il servizio è effettivamente pronto, risposta che può variare a seconda di vari fattori, come reperibilità di servizi terzi, oppure, se inserito all'interno di un container, possiamo utilizzare i controlli Health Check per sapere se il container e l'applicazione sono stati inizializzati correttamente.

Essendo l'Health Check eseguito side-by-side all'applicazione, l'implementazione inizierà dal file Program.cs abilitando il servizio, ed aggiungendone uno creato ad-hoc per gRPC, fornito dal namespace Grpc.HealthCheck, infine svilupperemo un BackgroundService nel quale scriveremo la logica che stabilirà lo stato.

using Grpc.HealthCheck;

builder.Services.AddHealthChecks();
builder.Services.AddSingleton<HealthServiceImpl>();
builder.Services.AddHostedService<StatusService>();

All'interno del BackgroundService controlliamo, tramite un ciclo infinito intervallato da un timer, nel metodo ExecuteAsync, lo stato del servizio attraverso le istanze di HealthServiceImpl e HealthCheckService

using Grpc.Health.V1;
using Grpc.HealthCheck;
using Microsoft.Extensions.Diagnostics.HealthChecks;

public class StatusService : BackgroundService
{
    private readonly HealthServiceImpl _healthService;
    private readonly HealthCheckService _healthCheckService;

    public StatusService(HealthServiceImpl healthService, HealthCheckService healthCheckService)
    {
        _healthService = healthService;
        _healthCheckService = healthCheckService;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            var health = await _healthCheckService.CheckHealthAsync(stoppingToken);

            _healthService.SetStatus("MyService",
                health.Status == HealthStatus.Healthy
                    ? HealthCheckResponse.Types.ServingStatus.Serving
                    : HealthCheckResponse.Types.ServingStatus.NotServing);

            await Task.Delay(TimeSpan.FromSeconds(15), stoppingToken);
        }
    }
}

Alla nostra applicazione non resterà altro che esporre questa informazione verso l'esterno: tornando al Program.cs inseriamo l'endpoint per conoscere l'Health Check ed eseguiamo il mapping del servizio gRPC apposito.

app.MapHealthChecks("/health");
app.MapGrpcService<HealthServiceImpl>();

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi