Middle+
Koje obrasce mikroservisa poznajete?
sobes.tech АИ
Одговор од АИ
- Otkrivanje usluga: Omogućava servisima da pronađu jedni druge. Implementira se putem centralizovanog registra (npr. ZooKeeper, Consul, etcd).
- API Gateway: Jedinstvena tačka ulaza za klijente, usmerava zahteve ka odgovarajućim servisima. Obezbeđuje autentifikaciju, autorizaciju, balansiranje opterećenja.
- Circuit Breaker (Automatski prekidač): Sprečava lančane padove, privremeno isključujući pozive ka neispravnim servisima.
- Bulkhead: Izoluje resurse različitih servisa, sprečavajući njihovo međusobno uticanje pri padovima.
- Saga: Upravljanje distribuiranim transakcijama, obezbeđujući konzistentnost podataka između više servisa putem sekvenci lokalnih transakcija i kompenzacionih radnji.
- Event Sourcing (Skladištenje zasnovano na događajima): Čuva sve promene podataka u obliku sekvence događaja, obezbeđujući potpunu istoriju stanja.
- CQRS (Razdvajanje odgovornosti za komande i upite): Odvaja logiku čitanja i pisanja podataka u različite modele, optimizujući performanse za svaki tip operacije.
- Database per Service: Svaki servis ima sopstvenu bazu podataka radi nezavisnosti i decentralizacije.
- Strangler Fig: Postepeno zamenjuje monolitnu aplikaciju mikroservisima, preusmeravajući deo saobraćaja.
Primer implementacije Circuit Breaker u PHP (pseudo-kod):
<?php
// Klasa Circuit Breaker
class CircuitBreaker
{
private $threshold; // Praga za greške
private $timeout; // Vreme ostanka otvorenog
private $failures = 0; // Trenutni broj grešaka
private $lastFailureTime = 0; // Vreme poslednje greške
private $state = 'CLOSED'; // Trenutno stanje: 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';
// Pokušaj u HALF_OPEN
try {
$result = $operation();
$this->reset(); // Uspeh, reset
return $result;
} catch (\Exception $e) {
$this->recordFailure(); // Neuspeh u HALF_OPEN, nazad na OPEN
throw $e;
}
} else {
throw new \Exception("Circuit breaker je otvoren");
}
break;
case 'HALF_OPEN':
// Logika za HALF_OPEN
break;
case 'CLOSED':
default:
try {
$result = $operation();
$this->reset(); // Uspeh, reset
return $result;
} catch (\Exception $e) {
$this->recordFailure(); // Greška, povećaj brojač
throw $e;
}
break;
}
}
private function recordFailure(): void
{
$this->failures++;
$this->lastFailureTime = time();
if ($this->failures >= $this->threshold) {
$this->state = 'OPEN'; // Prelaz u OPEN
}
}
private function reset(): void
{
$this->failures = 0;
$this->lastFailureTime = 0;
$this->state = 'CLOSED'; // Prelaz u CLOSED
}
}
// Upotreba
$breaker = new CircuitBreaker(3, 60); // Prag 3 greške, timeout 60 sekundi
try {
$data = $breaker->execute(function() {
// Kod za poziv spoljašnje usluge
if (rand(0, 1) == 0) { // Simulacija greške
throw new \Exception("Usluga nedostupna");
}
return ['status' => 'ok'];
});
echo "Uspeh: " . json_encode($data) . "\n";
} catch (\Exception $e) {
echo "Greška: " . $e->getMessage() . "\n";
}