Sobes.tech
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";
}