Tutoriels26 décembre 2025 11 min de lecture

Protocole Health Checking gRPC : Implémentation et Monitoring

Implémentez le protocole standard de health checking gRPC. Configuration, intégration Kubernetes et bonnes pratiques pour services gRPC résilients.

WizStatus Team
Auteur

gRPC s'est imposé comme le standard pour la communication inter-services haute performance. Avec cette adoption vient le besoin de mécanismes robustes de health checking.

Le gRPC Health Checking Protocol standardise la façon dont les services rapportent leur état de santé. Ce protocole facilite l'intégration avec Kubernetes et les service meshes.

Qu'est-ce que le Protocole Health Checking gRPC ?

Le gRPC Health Checking Protocol est une spécification définissant un service gRPC standard pour rapporter l'état de santé. Il utilise Protocol Buffers pour garantir l'interopérabilité.

Définition du service

Le service Health est défini en protobuf :

syntax = "proto3";

package grpc.health.v1;

service Health {
  // Check synchrone
  rpc Check(HealthCheckRequest) returns (HealthCheckResponse);

  // Watch streaming - reçoit les changements en temps réel
  rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
}

message HealthCheckRequest {
  string service = 1;  // Vide pour le statut global
}

message HealthCheckResponse {
  enum ServingStatus {
    UNKNOWN = 0;
    SERVING = 1;
    NOT_SERVING = 2;
    SERVICE_UNKNOWN = 3;  // Utilisé par Watch uniquement
  }
  ServingStatus status = 1;
}

Les deux méthodes

Le service expose deux méthodes complémentaires :

MéthodeDescriptionUsage
CheckVérification synchroneLoad balancers, probes
WatchStream de changementsRéaction temps réel

Statuts possibles

Les statuts sont clairement définis :

  • UNKNOWN : Statut inconnu (valeur par défaut)
  • SERVING : Le service accepte les requêtes
  • NOT_SERVING : Le service refuse les requêtes
  • SERVICE_UNKNOWN : Le service demandé n'existe pas

Granularité par service

Un serveur gRPC peut héberger plusieurs services logiques :

// Requête pour le statut global
healthClient.Check(ctx, &grpc_health_v1.HealthCheckRequest{
    Service: "",  // Vide = statut global
})

// Requête pour un service spécifique
healthClient.Check(ctx, &grpc_health_v1.HealthCheckRequest{
    Service: "mypackage.MyService",
})

Pourquoi le Health Checking gRPC est Essentiel

Intégration Kubernetes native

Kubernetes supporte nativement les probes gRPC depuis la version 1.24 :

apiVersion: v1
kind: Pod
spec:
  containers:
  - name: grpc-server
    ports:
    - containerPort: 50051
    livenessProbe:
      grpc:
        port: 50051
        service: ""  # Statut global
      initialDelaySeconds: 10
      periodSeconds: 5
    readinessProbe:
      grpc:
        port: 50051
        service: "mypackage.MyService"
      periodSeconds: 3
L'intégration native simplifie la configuration. Plus besoin d'un sidecar ou d'un endpoint HTTP séparé pour les health checks.

Load balancing intelligent

Les load balancers gRPC-aware utilisent le protocole pour détecter les instances unhealthy :

# Configuration Envoy
health_checks:
  - timeout: 1s
    interval: 5s
    grpc_health_check:
      service_name: "mypackage.MyService"

Avantage de Watch

La méthode Watch offre une détection instantanée :

// Au lieu de poller toutes les 5 secondes
stream, _ := healthClient.Watch(ctx, &grpc_health_v1.HealthCheckRequest{})
for {
    resp, _ := stream.Recv()
    // Notification immédiate des changements
    handleStatusChange(resp.Status)
}
Watch établit un stream où les changements sont poussés instantanément. Cette approche réactive améliore la vitesse de détection par rapport au polling.

Comment Implémenter le Health Checking gRPC

Implémentation en Go

Utilisez le package grpc-go/health :

package main

import (
    "google.golang.org/grpc"
    "google.golang.org/grpc/health"
    "google.golang.org/grpc/health/grpc_health_v1"
)

func main() {
    server := grpc.NewServer()

    // Créer le service de santé
    healthServer := health.NewServer()

    // Enregistrer le service Health
    grpc_health_v1.RegisterHealthServer(server, healthServer)

    // Définir le statut initial
    healthServer.SetServingStatus("", grpc_health_v1.HealthCheckResponse_NOT_SERVING)
    healthServer.SetServingStatus("mypackage.MyService", grpc_health_v1.HealthCheckResponse_NOT_SERVING)

    // Démarrer le serveur
    go func() {
        server.Serve(listener)
    }()

    // Une fois initialisé, passer à SERVING
    healthServer.SetServingStatus("", grpc_health_v1.HealthCheckResponse_SERVING)
    healthServer.SetServingStatus("mypackage.MyService", grpc_health_v1.HealthCheckResponse_SERVING)
}

Gestion du cycle de vie

Implémentez la logique de changement de statut :

func (s *Server) Shutdown() {
    // 1. Signaler NOT_SERVING immédiatement
    s.healthServer.SetServingStatus("", grpc_health_v1.HealthCheckResponse_NOT_SERVING)

    // 2. Attendre le drainage des connexions
    time.Sleep(5 * time.Second)

    // 3. Arrêter gracefully
    s.grpcServer.GracefulStop()
}

Vérification des dépendances

Surveillez les dépendances de manière asynchrone :

func (s *Server) monitorDependencies(ctx context.Context) {
    ticker := time.NewTicker(5 * time.Second)
    defer ticker.Stop()

    for {
        select {
        case <-ctx.Done():
            return
        case <-ticker.C:
            dbHealthy := s.checkDatabase()
            cacheHealthy := s.checkCache()

            if dbHealthy && cacheHealthy {
                s.healthServer.SetServingStatus("", grpc_health_v1.HealthCheckResponse_SERVING)
            } else {
                s.healthServer.SetServingStatus("", grpc_health_v1.HealthCheckResponse_NOT_SERVING)
            }
        }
    }
}
Évitez de vérifier les dépendances synchronement dans Check. Cela garantit des temps de réponse rapides pour les health checks.

Test avec grpc-health-probe

Utilisez l'outil officiel pour tester :

# Installation
go install github.com/grpc-ecosystem/grpc-health-probe@latest

# Test du statut global
grpc-health-probe -addr=localhost:50051

# Test d'un service spécifique
grpc-health-probe -addr=localhost:50051 -service=mypackage.MyService

# Avec timeout
grpc-health-probe -addr=localhost:50051 -connect-timeout=1s -rpc-timeout=1s

Bonnes Pratiques Health Checking gRPC

Distinguez liveness et readiness

Utilisez des vérifications différentes :

// Liveness - minimal et rapide
healthServer.SetServingStatus("liveness", grpc_health_v1.HealthCheckResponse_SERVING)

// Readiness - vérifie les dépendances
func updateReadiness() {
    if allDependenciesHealthy() {
        healthServer.SetServingStatus("readiness", grpc_health_v1.HealthCheckResponse_SERVING)
    } else {
        healthServer.SetServingStatus("readiness", grpc_health_v1.HealthCheckResponse_NOT_SERVING)
    }
}

Shutdown graceful

Séquencez correctement l'arrêt :

func gracefulShutdown(s *Server, sig os.Signal) {
    log.Printf("Received signal %v, starting graceful shutdown", sig)

    // 1. Marquer comme NOT_SERVING
    s.healthServer.SetServingStatus("", grpc_health_v1.HealthCheckResponse_NOT_SERVING)

    // 2. Attendre que les probes détectent le changement
    time.Sleep(s.config.GracePeriod)

    // 3. Drainer les connexions existantes
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    done := make(chan struct{})
    go func() {
        s.grpcServer.GracefulStop()
        close(done)
    }()

    select {
    case <-done:
        log.Println("Graceful shutdown completed")
    case <-ctx.Done():
        log.Println("Forcing shutdown")
        s.grpcServer.Stop()
    }
}

Timeouts appropriés

Configurez des timeouts raisonnables :

# Kubernetes probe configuration
livenessProbe:
  grpc:
    port: 50051
  initialDelaySeconds: 15  # Temps de démarrage
  periodSeconds: 10
  timeoutSeconds: 3        # Doit répondre en 3s
  failureThreshold: 3      # 3 échecs avant redémarrage

Logging des transitions

Loguez chaque changement de statut :

func (s *Server) setStatus(service string, status grpc_health_v1.HealthCheckResponse_ServingStatus) {
    previousStatus := s.currentStatus[service]
    s.healthServer.SetServingStatus(service, status)
    s.currentStatus[service] = status

    if previousStatus != status {
        log.Printf("Health status changed: service=%s, from=%s, to=%s",
            service, previousStatus, status)
    }
}

Tests de scénarios de défaillance

Testez les comportements de health check :

func TestHealthCheckDuringDbOutage(t *testing.T) {
    server := NewTestServer()

    // Simuler une panne DB
    server.mockDB.SetAvailable(false)

    // Attendre la mise à jour du health check
    time.Sleep(6 * time.Second)

    // Vérifier le statut
    resp, _ := server.healthClient.Check(ctx, &grpc_health_v1.HealthCheckRequest{})
    assert.Equal(t, grpc_health_v1.HealthCheckResponse_NOT_SERVING, resp.Status)
}

Conclusion

Le protocole gRPC Health Checking standardise l'observabilité des services gRPC. En l'implémentant correctement, vos services s'intègrent naturellement avec :

  • Kubernetes
  • Service meshes (Istio, Linkerd)
  • Load balancers (Envoy, Traefik)

Cette standardisation améliore la résilience globale de votre architecture microservices.

WizStatus peut surveiller la disponibilité de vos services gRPC et vous alerter en cas de changement de statut de santé.

Articles connexes

Monitoring API : Bonnes Pratiques et Stratégies 2026
Monitoring

Monitoring API : Bonnes Pratiques et Stratégies 2026

Maîtrisez le monitoring de vos APIs avec les meilleures pratiques 2025. Métriques essentielles, alertes intelligentes et observabilité pour des APIs performantes.
18 min de lecture
Monitoring du Rate Limiting API : Métriques et Alertes
Monitoring

Monitoring du Rate Limiting API : Métriques et Alertes

Surveillez efficacement votre rate limiting API. Détection des abus, optimisation des quotas et préservation de l'expérience utilisateur légitime.
9 min de lecture
Optimisation du Temps de Réponse API : Techniques et Stratégies
Bonnes Pratiques

Optimisation du Temps de Réponse API : Techniques et Stratégies

Optimisez les performances de vos APIs avec des techniques éprouvées. Caching, async, compression et bonnes pratiques pour des temps de réponse minimaux.
13 min de lecture

Commencez à surveiller votre infrastructure dès aujourd'hui

Mettez ces conseils en pratique avec le monitoring WizStatus.

Essayer WizStatus Gratuitement