Microservices / Distributed Systems

Saga Pattern

Distributed transactions bez 2PC — sekwencja lokalnych transakcji z kompensacją. Choreography przez eventy lub Orchestration przez Temporal.io.

Eventual Consistency
Zamiast 2PC
Choreography
Event-driven
Orchestration
Centralny koord.
Temporal.io
Durable workflows

Choreography vs Orchestration

Dwa fundamentalnie różne podejścia do koordynacji Sagi — decentralizacja przez eventy vs centralny koordynator.

AspektChoreographyOrchestration
KoordynacjaZdecentralizowana (events)Centralna (Saga Manager)
CouplingLuźne (event bus)Wyższe (orchestrator zna usługi)
DebugowanieTrudne (rozproszone logi)Łatwe (centralny log)
Widoczność stanuBrak centralnego widokuPełny widok stanu
Dodawanie krokówProste (nowy subscriber)Wymaga zmiany orchestratora
NarzędziaKafka, RabbitMQ, SNS/SQSTemporal, Step Functions, Zeebe

Często zadawane pytania

Co to jest wzorzec Saga i dlaczego zastępuje distributed transactions?

Problem: w mikrousługach nie ma jednej bazy danych dla całej transakcji. Distributed transactions (2PC — Two-Phase Commit) wymagają distributed lock — powolne, kruche, nie skalują się. Saga pattern: zamiast jednej ACID transakcji — sekwencja lokalnych transakcji powiązanych kompensacją. Każdy krok to lokalna transakcja w jednej usłudze. Jeśli krok się nie powiedzie — uruchom compensating transactions dla poprzednich kroków. Saga nie jest ACID: brak Isolation — inne usługi mogą widzieć częściowe rezultaty. Eventual Consistency — spójność osiągana po czasie. Bazedanowe 'BASE' zamiast 'ACID'. Przykład: Order Saga. 1. CreateOrder (PENDING). 2. ReserveInventory. 3. ProcessPayment. 4. ConfirmOrder. Jeśli payment fail: CancelReservation (compensate 2). CancelOrder (compensate 1). Dwie implementacje Saga: Choreography — zdarzenia (events) koordynują przepływ. Orchestration — centralny koordynator (Orchestrator/Saga Manager) steruje krokami. Brak Isolation powoduje anomalie: Lost Update. Dirty Read. Non-repeatable Read. Countermeasures: Semantic Lock — flaguj rekordy jako 'w trakcie przetwarzania'. Commutative Updates — kolejność nie ma znaczenia. Pessimistic View — re-read po zakończeniu.

Choreography Saga vs Orchestration Saga — co wybrać?

Choreography Saga: każda usługa reaguje na eventy i emituje własne eventy. Brak centralnego koordynatora. Przepływ: OrderService emituje 'OrderCreated' -> InventoryService reaguje, emituje 'InventoryReserved' -> PaymentService reaguje, emituje 'PaymentProcessed' -> OrderService reaguje, emituje 'OrderConfirmed'. Kompensacja: PaymentService emituje 'PaymentFailed' -> InventoryService reaguje 'InventoryReleased' -> OrderService emituje 'OrderCancelled'. Zalety choreography: brak single point of failure. Luźne powiązania. Łatwo dodać nową usługę (subscriber). Wady choreography: trudne debugowanie (gdzie jest błąd?). Brak centralnego widoku stanu. Ryzyko cyklicznych zależności. Spaghetti event flow. Orchestration Saga: centralny Orchestrator (Saga Manager) wysyła komendy do usług, czeka na odpowiedź. Orchestrator wie o wszystkich krokach i stanie. Zalety orchestration: łatwiejsze debugowanie. Jasny przepływ. Łatwe retry. Czytelna logika biznesowa w jednym miejscu. Wady orchestration: Orchestrator wie o wszystkich usługach (higher coupling). Single point of coordination. Kiedy co: prosta Saga (2-3 kroki) — choreography. Złożona logika, wiele kroków, retry — orchestration. Temporal.io — workflow engine dla orchestration Saga.

Temporal.io — durable workflow engine dla Saga i długotrwałych procesów?

Temporal.io: open-source durable workflow engine. Napędzany przez Netflix, Uber, Airbnb. Kluczowa idea: kod workflow jest deterministyczny i persystowany. Workflow może czekać dni/tygodnie bez utraty stanu. Crash i restart nie zrywają workflow. Koncepty: Workflow — kod który definiuje przepływ. Activity — pojedynczy krok (call do zewnętrznego API, DB write). Worker — serwis który wykonuje workflow i activities. Task Queue — kolejka zadań dla workerów. Signals — zewnętrzne zdarzenia które modyfikują workflow. Queries — odczyt stanu workflow. Jak działa: Temporal Server persystuje każdy krok. Při restart Worker — odtwarza historię eventów i kontynuuje. Automatyczne retry activities (z exponential backoff). Timeout per activity i per workflow. Saga z Temporal: każda Activity jest odwracalna (compensate function). Jeśli Activity fail — Temporal uruchamia compensation workflow. Języki: Go, Java, Python, TypeScript (SDK). Temporal Cloud: managed Temporal (pay per use). Self-hosted: Temporal Server + Cassandra/PostgreSQL. Alternatywy: Conductor (Netflix, open-source). Cadence (Uber, Temporal ancestor). AWS Step Functions (SaaS, state machines). Zeebe/Camunda 8 (BPMN-based). Apache Airflow (DAG-based, bardziej dla ETL).

Jak implementować Saga z Kafka i event store?

Event-driven Saga z Kafka: każdy krok emituje eventy na Kafka topic. Usługi konsumują eventy i emitują nowe. Compensating events publikowane w przypadku błędu. Saga State: gdzie trzymać stan sagi? Opcja 1: Saga State w osobnej tabeli DB per usługa. Opcja 2: Event Store — stan wynikający z historii eventów. Opcja 3: Redis — tymczasowy state dla in-flight sagas. Choreography z Kafka: topics per step/event-type. Idempotent consumers — ten sam event może przyjść wielokrotnie. Consumer groups — jedna instancja per partycja. Exactly-once semantics: Kafka transactions — producer i consumer jako atomowa operacja. Transactional Outbox — najpierw zapisz do DB, potem do Kafka (CDC przez Debezium). Saga correlation: Correlation ID — ten sam ID przez całą sagę. Propagowany w event headers lub payload. Używany do łączenia eventów w jedną sagę. Observability: distributed tracing (OpenTelemetry) z correlation ID. Metryki: saga duration, success rate, compensation rate. Alerting gdy saga stuck (brak postępu po X minutes). Testing Saga: unit test każdej usługi niezależnie. Contract tests (Pact) między usługami. Integration tests z testcontainers (Kafka + PostgreSQL). End-to-end saga test w staging environment.

Jakie są pułapki i anty-wzorce przy implementacji Saga?

Pułapka 1 — Missing compensation: każdy krok MUSI mieć compensating transaction. Jeśli krok nie może być cofnięty (np. email już wysłany) — użyj Pivot Transaction (ostatni krok który można cofnąć). Pułapka 2 — Dirty reads: usługa B czyta dane które usługa A jeszcze modyfikuje w ramach innej sagi. Countermeasure: Semantic Lock (flaga 'PENDING' w rekordzie). Pułapka 3 — Saga stuck: event zgubiony, usługa down — saga nigdy się nie kończy. Rozwiązanie: monitoring + alerting na długo trwające sagi. Dead letter queue. Manual intervention workflow. Pułapka 4 — Idempotency brak: event dostarczony dwukrotnie -> podwójna rezerwacja. Każdy krok musi być idempotentny. Pułapka 5 — Synchronous coordination: Saga przez synchroniczne HTTP zamiast events. Tworzy temporal coupling, traci odporność na awarie. Pułapka 6 — Zbyt dużo kroków: 10+ kroków Saga = koszmar debugowania. Rozbij na mniejsze sagas lub przemyśl granice serwisów. Best practices: Saga per business process (Order, Payment, Shipping oddzielne). Idempotent activities/handlers. Compensation zawsze implementowana. Monitoring i timeout per saga. Semantic Lock dla isolation. Testuj kompensację tak samo jak happy path.

Kontakt

Skontaktuj się z nami

Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.

Wyślij zapytanie

Bezpłatna wycena w 24h
Bez zobowiązań
Indywidualne podejście
Ekspresowa realizacja

Telefon

+48 790 814 814

Pon-Pt: 9:00 - 18:00

Email

adam@fotz.pl

Odpowiadamy w ciągu 24h

Adres rejestrowy

Poznańska 117/11

62-023 Kamionki · obsługa zdalna

Godziny pracy

Pon - Pt9:00 - 18:00
Sob - NdzZamknięte

Wolisz porozmawiać?

Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.

Zadzwoń teraz