Sobes.tech
Middle+

Quels modèles de microservices connaissez-vous?

sobes.tech IA

Réponse de l'IA

  • Découverte de services: Permet aux services de se trouver mutuellement. Implémenté via un registre centralisé (par exemple, ZooKeeper, Consul, etcd).
  • API Gateway: Point d'entrée unique pour les clients, acheminant les requêtes vers les services appropriés. Fournit authentification, autorisation et équilibrage de charge.
  • Circuit Breaker (Disjoncteur): Empêche les défaillances en cascade, en désactivant temporairement les appels aux services défectueux.
  • Bulkhead: Isole les ressources de différents services, évitant leur influence mutuelle en cas de défaillance.
  • Saga: Gère les transactions distribuées, assurant la cohérence des données entre plusieurs services via une séquence de transactions locales et d'actions compensatoires.
  • Event Sourcing (Stockage basé sur les événements): Enregistre toutes les modifications de données sous forme de séquences d'événements, fournissant un historique complet des états.
  • CQRS (Segregation des responsabilités Commande et Requête): Divise la logique de lecture et d'écriture des données en modèles différents, optimisant la performance pour chaque type d'opération.
  • Base de données par service: Chaque service dispose de sa propre base de données pour garantir l'indépendance et la décentralisation.
  • Strangler Fig: Remplacement progressif d'une application monolithique par des microservices, en redirigeant une partie du trafic.

Exemple d'implémentation de Circuit Breaker en PHP (pseudocode):

<?php
// Classe Circuit Breaker
class CircuitBreaker
{
    private $threshold; // Seuil de défaillances
    private $timeout; // Temps pendant lequel le disjoncteur reste ouvert
    private $failures = 0; // Nombre actuel de défaillances
    private $lastFailureTime = 0; // Temps de la dernière défaillance
    private $state = 'CLOSED'; // État actuel: CLOSED, OPEN, HALF_OPEN

    public function __construct(int $threshold, int $timeout)
    {
        $this->threshold = $threshold;
        $this->timeout = $timeout;
    }

    public function execute(callable $operation)
    {
        switch ($this->state) {
            case 'OPEN':
                if (time() - $this->lastFailureTime > $this->timeout) {
                    $this->state = 'HALF_OPEN';
                    // Tentative d'exécution en état HALF-OPEN
                    try {
                        $result = $operation();
                        $this->reset(); // Succès, réinitialiser
                        return $result;
                    } catch (\Exception $e) {
                        $this->recordFailure(); // Échec en HALF-OPEN, revenir à OPEN
                        throw $e;
                    }
                } else {
                    throw new \Exception("Circuit breaker is open"); // Disjoncteur ouvert
                }
                break;
            case 'HALF_OPEN':
                // La logique en HALF_OPEN est déjà ci-dessus
                break;
            case 'CLOSED':
            default:
                try {
                    $result = $operation();
                    $this->reset(); // Succès, réinitialiser
                    return $result;
                } catch (\Exception $e) {
                    $this->recordFailure(); // Échec, incrémenter le compteur
                    throw $e;
                }
                break;
        }
    }

    private function recordFailure(): void
    {
        $this->failures++;
        $this->lastFailureTime = time();
        if ($this->failures >= $this->threshold) {
            $this->state = 'OPEN'; // Passage à OPEN au seuil
        }
    }

    private function reset(): void
    {
        $this->failures = 0;
        $this->lastFailureTime = 0;
        $this->state = 'CLOSED'; // Passage à CLOSED en cas de succès
    }
}

// Utilisation
$breaker = new CircuitBreaker(3, 60); // Seuil 3 défaillances, timeout 60 secondes

try {
    $data = $breaker->execute(function() {
        // Code d'appel à un service externe
        if (rand(0, 1) == 0) { // Simulation d'échec
             throw new \Exception("Service unavailable");
        }
        return ['status' => 'ok'];
    });
    echo "Success: " . json_encode($data) . "\n";
} catch (\Exception $e) {
    echo "Failure: " . $e->getMessage() . "\n";
}