Sobes.tech
Middle+

Jaké vzory mikroservisů znáte?

sobes.tech AI

Odpověď od AI

  • Objevování služeb: Umožňuje službám navzájem se najít. Implementuje se prostřednictvím centralizovaného registru (například ZooKeeper, Consul, etcd).
  • API Gateway: Jednotný vstupní bod pro klienty, směruje požadavky na odpovídající služby. Zajišťuje autentizaci, autorizaci, vyvažování zátěže.
  • Circuit Breaker (Automatický vypínač): Zabraňuje kaskádovým selháním tím, že dočasně vypne volání do selhávajících služeb.
  • Bulkhead: Izoluje zdroje různých služeb, předchází jejich vzájemnému ovlivnění při selhání.
  • Saga: Řídí distribuované transakce, zajišťuje konzistenci dat mezi více službami pomocí sekvence lokálních transakcí a kompenzačních akcí.
  • Event Sourcing (Uchovávání podle událostí): Ukládá všechny změny dat ve formě sekvence událostí, poskytuje úplnou historii stavů.
  • CQRS (Oddělení odpovědnosti příkazů a dotazů): Odděluje logiku čtení a zápisu dat do různých modelů, optimalizuje výkon pro každý typ operace.
  • Database per Service: Každá služba má vlastní databázi pro zajištění nezávislosti a decentralizace.
  • Strangler Fig: Postupná náhrada monolitické aplikace mikroservisy, přesměrováním části provozu.

Příklad implementace Circuit Breaker v PHP (pseudokód):

<?php
// Třída Circuit Breaker
class CircuitBreaker
{
    private $threshold; // Prahová hodnota chyb
    private $timeout; // Čas, po který zůstává vypínač otevřený
    private $failures = 0; // Aktuální počet chyb
    private $lastFailureTime = 0; // Čas poslední chyby
    private $state = 'CLOSED'; // Aktuální stav: 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';
                    // Pokus v HALF_OPEN
                    try {
                        $result = $operation();
                        $this->reset(); // Úspěch, reset
                        return $result;
                    } catch (\Exception $e) {
                        $this->recordFailure(); // Selhání v HALF_OPEN, zpět na OPEN
                        throw $e;
                    }
                } else {
                    throw new \Exception("Circuit breaker je otevřený");
                }
                break;
            case 'HALF_OPEN':
                // Logika pro HALF_OPEN
                break;
            case 'CLOSED':
            default:
                try {
                    $result = $operation();
                    $this->reset(); // Úspěch, reset
                    return $result;
                } catch (\Exception $e) {
                    $this->recordFailure(); // Chyba, zvýšení počtu
                    throw $e;
                }
                break;
        }
    }

    private function recordFailure(): void
    {
        $this->failures++;
        $this->lastFailureTime = time();
        if ($this->failures >= $this->threshold) {
            $this->state = 'OPEN'; // Přechod na OPEN
        }
    }

    private function reset(): void
    {
        $this->failures = 0;
        $this->lastFailureTime = 0;
        $this->state = 'CLOSED'; // Přechod na CLOSED
    }
}

// Použití
$breaker = new CircuitBreaker(3, 60); // Prah 3 selhání, timeout 60 sekund

try {
    $data = $breaker->execute(function() {
        // Kód volání externí služby
        if (rand(0, 1) == 0) { // Simulace selhání
             throw new \Exception("Služba nedostupná");
        }
        return ['status' => 'ok'];
    });
    echo "Úspěch: " . json_encode($data) . "\n";
} catch (\Exception $e) {
    echo "Selhání: " . $e->getMessage() . "\n";
}