Zaimplementuj centralny Saga Orchestrator używając Temporal lub Netflix Conductor, który utrzymuje trwały stan workflow w PostgreSQL z komunikacją gRPC do usług domenowych. Wzór wymaga kluczy idempotencyjnych przechowywanych w Redis Cluster z oknami TTL zgodnymi z ograniczeniami biznesowymi, podczas gdy Apache Kafka służy jako podstawa zdarzeń dla audytów i wyzwalaczy rekompensacyjnych. Każdy krok sagi musi zawierać transakcje rekompensacyjne, które wykonują operacje odwrotne, wykorzystując wzór Saga State Machine, z wyraźnymi stanami (PENDING, SUCCEEDED, COMPENSATING, COMPENSATED) śledzonymi w etcd lub ZooKeeper dla koordynacji klastra.
┌─────────────────┐ ┌──────────────┐ ┌─────────────────┐
│ API Gateway │────▶│ Temporal │────▶│ Inventory │
└─────────────────┘ │ Orchestrator│ │ Service │
└──────────────┘ └─────────────────┘
│ │
▼ ▼
┌──────────────┐ ┌─────────────────┐
│ PostgreSQL │ │ PostgreSQL │
│ State Store │ │ (Logic │
└──────────────┘ │ Compensation) │
└─────────────────┘
Globalna platforma rezerwacji hoteli zmagała się z kaskadowymi awariami podczas koordynacji rezerwacji pokoi, przetwarzania płatności oraz aktualizacji punktów lojalnościowych w trzech różnych klastrach Kubernetes w różnych regionach. Ich starsza implementacja używała Two-Phase Commit (2PC) przez REST API, co powodowało powszechne blokady podczas szczytowego ruchu, gdy brama płatności doświadczała opóźnień przekraczających 10 sekund.
Zespół ocenił Choreography-Based Saga korzystając z Amazon EventBridge, gdzie każda usługa publikowała zdarzenia domenowe na wspólnym autobusie. Podejście to wyeliminowało pojedynczy punkt awarii i zmniejszyło koszty infrastruktury o 40%. Jednak wprowadziło poważne wyzwania w zakresie obserwacji, gdyż określenie, czy złożona rezerwacja wielu pokoi się powiodła, wymagało przeszukiwania logów w siedemnastu mikrousługach. Implikowane zależności uniemożliwiły egzekwowanie spójnych polityk czasowych, a debugowanie problemów produkcyjnych stało się dochodzeniowym ćwiczeniem obejmującym wiele pulpitów AWS CloudWatch.
Zaprojektowali prototyp Orchestrated Saga przy użyciu niestandardowego koordynatora Node.js wdrożonego na AWS ECS. To zcentralizowało logikę biznesową i uprościło monitorowanie przez zintegrowany pulpit nawigacyjny Grafana. Niestety, początkowa implementacja przechowywała stan workflow tylko w pamięci, co skutkowało katastrofalną utratą danych, gdy koordynator został ponownie uruchomiony podczas wdrożeń. Trzydzieści transakcji weszło w nieznane stany, wymagając ręcznej rekonsyliacji bazy danych, co zajęło trzy dni i spowodowało znaczące straty przychodów z powodu podwójnie obciążonych klientów.
Wybrane rozwiązanie wdrożyło Temporal jako silnik workflow z trwaniem w Cassandra, zapewniając trwałość stanu w przypadku ponownego uruchamiania podów i awarii AZ. Architektura używała schematów Protobuf do bezpiecznej komunikacji typu między koordynatorem a usługami domenowymi, z Redis Sentinel zarządzającym kluczami idempotencyjnymi. Gdy usługa płatności doświadczyła awarii regionalnej w us-east-1, saga automatycznie wyzwoliła workflow rekompensacyjne, które zwolniły zablokowane pokoje w ciągu 200ms i cofnęły punkty lojalnościowe atomowo.
System teraz przetwarza 50 000 złożonych rezerwacji dziennie z gwarancją spójności na poziomie 99,99% i zerowym interwencjonizmem ręcznym podczas podziałów sieciowych. Średni czas wykrywania (MTTD) awarii spadł z 45 minut do 8 sekund, a latencja rekompensacji pozostaje poniżej 500ms na p99.
Jak radzisz sobie z częściową awarią rekompensacji, gdy sama transakcja rekompensacyjna zawiedzie, potencjalnie pozostawiając system w niespójnym stanie?
Zaimplementuj Compensation Audit Log używając Event Sourcing, gdzie każda próba rekompensacji jest rejestrowana jako niezmienne zdarzenie w Apache Kafka z nieograniczonym przechowywaniem. System musi rozróżniać między przejrzystymi awariami infrastruktury, które wymagają automatycznego ponownego przetworzenia z rozkładem wykładniczym, a naruszeniami logiki biznesowej, które wymagają interwencji ludzkiej. W przypadku przejrzystych problemów użyj Dead Letter Queues (DLQ) w RabbitMQ lub Amazon SQS, które przetwarzają rekompensacje ponownie po odzyskaniu usługi, z jitterem, aby zapobiec stadem tysięcy. W przypadku naruszeń zasad biznesowych, takich jak próba zwrotu już rozliczonej transakcji, saga wchodzi w stan 'COMPENSATION_FAILED', który wyzwala alerty PagerDuty, podczas gdy stosuje wzór CQRS, aby zablokować korzeń agregatu za pomocą modelu polecenia. Zawsze projektuj rekompensacje jako idempotentne, używając unikalnych ograniczeń bazy danych lub operacji Redis SETNX, zapewniając, że ponowne przetwarzanie nie powoduje skutków ubocznych.
Jaka jest fundamentalna różnica architektoniczna między choreografią a orkiestracją w zakresie sprzężenia czasowego i możliwości odpowiadania na zapytania 'jaki jest aktualny stan transakcji'?
Choreografia podąża za Reactive Manifesto, tworząc sprzężenie czasowe, gdzie usługi reagują na zdarzenia bez wiedzy o uczestnikach upstream lub downstream, ale poświęcając możliwość zapytania o stan sagi bez budowania złożonego Distributed Tracing z Jaeger lub AWS X-Ray. Stan staje się wyłaniający się z dzienników zdarzeń, wymagając CQRS projekcji modeli odczytu, aby odpowiedzieć na pytania 'czy rezerwacja została ukończona'. Orkiestracja wprowadza wyraźne sprzężenie czasowe między koordynatorem a pracownikami, ponieważ koordynator musi być dostępny, aby wyzwanie następnych kroków, ale zapewnia jedno źródło prawdy w swoim magazynie stanów (PostgreSQL/CockroachDB). To umożliwia natychmiastowe zapytania o status, ale tworzy zależność sieciową. Krytycznym spostrzeżeniem jest to, że choreografia wymaga wdrożenia maszyn stanowych w każdym konsumencie, podczas gdy orkiestracja centralizuje tę złożoność; w systemach wymagających silnej audytowalności i zgodności (PCI-DSS), orkiestracja jest preferowana pomimo kosztu sprzężenia.
Jak zapobiegasz podwójnemu wykonaniu sagi, korzystając z semantyki dostarczania przynajmniej raz w brokerach wiadomości podczas ponownego bilansowania konsumentów Kafka lub ponownych uruchomień podów Kubernetes?
Zaimplementuj wzory Idempotent Consumer używając Redis lub Memcached do przechowywania ID przetworzonych wiadomości z oknami deduplikacji odpowiadającymi twojemu Recovery Point Objective (RPO), zwykle 24-48 godzin dla systemów finansowych. Gdy koordynator sagi otrzymuje polecenie, generuj deterministyczny klucz idempotencji poprzez haszowanie ID korelacji z kluczem biznesowym (ID klienta + referencja rezerwacji) przed wykonaniem jakichkolwiek skutków ubocznych. Każda usługa domenowa musi walidować ten klucz w swoim Idempotency Store, wdrożonym jako tabela PostgreSQL z unikalnymi ograniczeniami na kompozytowych kluczach lub Bloom Filters w Redis dla pamięciooperacyjnych negatywnych wyszukiwań. Dla długoterminowych sag używaj Saga State Machines z optymistycznym blokowaniem poprzez wersjonowanie etcd do obsługi semantyki przetwarzania dokładnie raz w rozproszonych węzłach. To zapobiega scenariuszom podwójnych rezerwacji, gdy grupy konsumentów balansują podczas wdrożeń lub podczas podziałów sieciowych, które wyzwalają restarty livenessProbe w Kubernetes.