Sobes.tech
Middle+

Кои модели на микросервизи знаете?

sobes.tech AI

Отговор от AI

  • Откриване на услуги: Позволява на услугите да се намират една друга. Реализира се чрез централизиран регистър (например ZooKeeper, Consul, etcd).
  • API Gateway: Единна точка за достъп за клиентите, маршрутизира заявки към съответните услуги. Осигурява автентикация, авторизация, баланс на натоварването.
  • Circuit Breaker (Автоматичен прекъсвач): Предотвратява каскадни сривове, временно изключвайки повиквания към дефектни услуги.
  • Bulkhead: Изолира ресурсите на различните услуги, предотвратявайки взаимното им влияние при сривове.
  • Saga: Управлява разпределени транзакции, осигурявайки съгласуваност на данните между няколко услуги чрез последователност от локални транзакции и компенсаторни действия.
  • Event Sourcing (Събитийно-ориентирано съхранение): Запазва всички промени в данните като последователност от събития, осигурявайки пълна история на състоянията.
  • CQRS (Разделяне на отговорностите за команда и заявка): Разделя логиката за четене и запис на данните в различни модели, оптимизирайки производителността за всеки тип операции.
  • Database per Service: Всяка услуга получава собствена база данни за осигуряване на независимост и децентрализация.
  • Strangler Fig: Постепенно замества монолитното приложение с микросервизи, пренасочвайки част от трафика.

Пример за реализация на Circuit Breaker в PHP (псевдокод):

<?php
// Клас Circuit Breaker
class CircuitBreaker
{
    private $threshold; // Праг на грешки
    private $timeout; // Време, през което остава отворен
    private $failures = 0; // Текущ брой грешки
    private $lastFailureTime = 0; // Време на последната грешка
    private $state = 'CLOSED'; // Текущо състояние: 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';
                    // Опит в HALF_OPEN
                    try {
                        $result = $operation();
                        $this->reset(); // Успех, нулиране
                        return $result;
                    } catch (\Exception $e) {
                        $this->recordFailure(); // Неуспех в HALF_OPEN, връщане към OPEN
                        throw $e;
                    }
                } else {
                    throw new \Exception("Circuit breaker е отворен");
                }
                break;
            case 'HALF_OPEN':
                // Логика за HALF_OPEN
                break;
            case 'CLOSED':
            default:
                try {
                    $result = $operation();
                    $this->reset(); // Успех, нулиране
                    return $result;
                } catch (\Exception $e) {
                    $this->recordFailure(); // Грешка, увеличаване на броя
                    throw $e;
                }
                break;
        }
    }

    private function recordFailure(): void
    {
        $this->failures++;
        $this->lastFailureTime = time();
        if ($this->failures >= $this->threshold) {
            $this->state = 'OPEN'; // Превключване към OPEN
        }
    }

    private function reset(): void
    {
        $this->failures = 0;
        $this->lastFailureTime = 0;
        $this->state = 'CLOSED'; // Превключване към CLOSED
    }
}

// Използване
$breaker = new CircuitBreaker(3, 60); // Праг 3 грешки, таймаут 60 сек

try {
    $data = $breaker->execute(function() {
        // Код за извикване на външна услуга
        if (rand(0, 1) == 0) { // Имитация на грешка
             throw new \Exception("Услугата е недостъпна");
        }
        return ['status' => 'ok'];
    });
    echo "Успех: " . json_encode($data) . "\n";
} catch (\Exception $e) {
    echo "Грешка: " . $e->getMessage() . "\n";
}