Sobes.tech
Middle+

Ce modele de microservicii cunoașteți?

sobes.tech AI

Răspuns de la AI

  • Descoperirea serviciilor: Permite serviciilor să se găsească reciproc. Se implementează printr-un registru centralizat (de exemplu, ZooKeeper, Consul, etcd).
  • API Gateway: Punct unic de intrare pentru clienți, redirecționează solicitările către serviciile corespunzătoare. Asigură autentificarea, autorizarea, echilibrarea încărcării.
  • Circuit Breaker (Comutator automat): Previne cascadele de erori, dezactivând temporar apelurile către serviciile defecte.
  • Bulkhead: Izolează resursele diferitelor servicii, prevenind influența reciprocă în caz de eșecuri.
  • Saga: Gestionează tranzacțiile distribuite, asigurând coerența datelor între mai multe servicii printr-o serie de tranzacții locale și acțiuni de compensare.
  • Event Sourcing (Stocare bazată pe evenimente): Stochează toate modificările datelor sub forma unei secvențe de evenimente, oferind o istorie completă a stărilor.
  • CQRS (Segregarea responsabilității între comandă și interogare): Separă logica de citire și scriere a datelor în modele diferite, optimizând performanța pentru fiecare tip de operație.
  • Database per Service (Bază de date pe serviciu): Fiecare serviciu are propria bază de date pentru independență și decentralizare.
  • Strangler Fig: Înlocuirea treptată a aplicației monolitice cu microservicii, redirecționând traficul.

Exemplu de implementare Circuit Breaker în PHP (pseudo-cod):

<?php
// Clasa Circuit Breaker
class CircuitBreaker
{
    private $threshold; // Pragul de erori
    private $timeout; // Timpul în care comutatorul rămâne deschis
    private $failures = 0; // Numărul curent de erori
    private $lastFailureTime = 0; // Timpul ultimei erori
    private $state = 'CLOSED'; // Starea curentă: 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';
                    // Încercare în starea HALF_OPEN
                    try {
                        $result = $operation();
                        $this->reset(); // Succes, reset
                        return $result;
                    } catch (\Exception $e) {
                        $this->recordFailure(); // Eșec în HALF_OPEN, înapoi la OPEN
                        throw $e;
                    }
                } else {
                    throw new \Exception("Circuit breaker este deschis"); // Comutatorul este deschis
                }
                break;
            case 'HALF_OPEN':
                // Logica pentru HALF_OPEN este mai sus
                break;
            case 'CLOSED':
            default:
                try {
                    $result = $operation();
                    $this->reset(); // Succes, reset
                    return $result;
                } catch (\Exception $e) {
                    $this->recordFailure(); // Eșec, incrementare
                    throw $e;
                }
                break;
        }
    }

    private function recordFailure(): void
    {
        $this->failures++;
        $this->lastFailureTime = time();
        if ($this->failures >= $this->threshold) {
            $this->state = 'OPEN'; // Trecere în OPEN
        }
    }

    private function reset(): void
    {
        $this->failures = 0;
        $this->lastFailureTime = 0;
        $this->state = 'CLOSED'; // Trecere în CLOSED
    }
}

// Utilizare
$breaker = new CircuitBreaker(3, 60); // Prag 3 erori, timeout 60 sec

try {
    $data = $breaker->execute(function() {
        // Cod pentru apel extern
        if (rand(0, 1) == 0) { // Simulare eșec
             throw new \Exception("Serviciu indisponibil");
        }
        return ['status' => 'ok'];
    });
    echo "Succes: " . json_encode($data) . "\n";
} catch (\Exception $e) {
    echo "Eșec: " . $e->getMessage() . "\n";
}