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";
}