Sobes.tech
Middle+

Ποια μοτίβα μικροϋπηρεσιών γνωρίζετε;

sobes.tech AI

Απάντηση από AI

  • Ανακάλυψη Υπηρεσιών: Επιτρέπει στις υπηρεσίες να βρίσκουν η μία την άλλη. Υλοποιείται μέσω ενός κεντρικού καταχωρητή (π.χ., ZooKeeper, Consul, etcd).
  • API Gateway: Μοναδικό σημείο εισόδου για τους πελάτες, δρομολογεί αιτήματα στις αντίστοιχες υπηρεσίες. Παρέχει αυθεντικοποίηση, εξουσιοδότηση, load balancing.
  • 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 αποτυχίες, timeout 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";
}