Strona główna / Warto wiedzieć ! / Architektura event-driven w e-commerce: 3 błędy, które niszczą skalowalność

Architektura event-driven w e-commerce: 3 błędy, które niszczą skalowalność

Wstęp: Kiedy system przestaje nadążać

Pracowałem ostatnio z klientem, który prowadzi sklep e-commerce z kilkudziesięcioma tysiącami transakcji dziennie. Wszystko działało dobrze – do czasu gdy wprowadzili kilka nowych integracji: płatności BNPL, system lojalnościowy, zewnętrzny fulfillment. Nagle czas odpowiedzi API zaczął rosnąć, a w szczycie pojawiały się timeouty. Klient był przekonany, że to wina hostingu. Po audycie okazało się, że problemem była architektura: każda operacja wywoływała szereg synchronicznych zależności, które blokowały główny wątek.

Rozwiązaniem była architektura event-driven. Ale czy każda implementacja kończy się sukcesem? Niestety nie. Widziałem wiele firm, które wdrożyły event-driven i… wpadły w nowe pułapki. W tym artykule pokażę 3 najczęstsze błędy, które zabijają skalowalność w e-commerce.

Czym jest event-driven w e-commerce?

Zanim przejdziemy do błędów – krótkie przypomnienie. W architekturze event-driven zamiast wywoływać usługi synchronicznie (np. po złożeniu zamówienia wywołujemy system magazynowy, potem płatności, potem wysyłkę), generujemy zdarzenie (np. „order.placed”) i wysyłamy je do brokera (np. Kafka, RabbitMQ, AWS EventBridge). Każda usługa subskrybuje interesujące ją zdarzenia i reaguje asynchronicznie.

Dzięki temu system staje się luźno powiązany, łatwiej skalowalny i bardziej odporny na awarie. Ale diabeł tkwi w szczegółach.

Błąd #1: Zbyt wiele synchronicznych zależności w event-handlerach

To najbardziej klasyczny błąd. Firma wdraża event-driven, ale w handlerach zdarzeń nadal wykonuje synchroniczne zapytania do innych usług. Na przykład: po zdarzeniu „order.placed” handler systemu lojalnościowego potrzebuje danych klienta z bazy CRM. Zamiast wcześniej wzbogacić zdarzenie o dane klienta, handler wykonuje synchroniczny request do CRM. Gdy CRM jest wolny, cały event się opóźnia. A gdy CRM pada, event się gubi.

Przykład z życia: Klient z sektora fashion miał system, w którym każde zdarzenie „order.placed” wywoływało 3 synchroniczne zapytania do różnych serwisów. W szczycie sezonu broker eventów zalał się, a kolejka rosła. Rozwiązanie? Wzbogacanie eventów o dane niezbędne do przetworzenia (enrichment) oraz wprowadzenie dedykowanych widoków danych (materialized views) w każdej usłudze.

Konsekwencje: Opóźnienia, gubienie eventów, utrata zamówień. W e-commerce każda sekunda zwłoki kosztuje konwersję.

Błąd #2: Brak strategii na eventy nieudane (failed events)

Event-driven nie oznacza, że wszystko zawsze działa. Czasami handler nie przetworzy eventu – błąd w logice, chwilowa niedostępność bazy, błędne dane. I co wtedy? Wiele firm po prostu loguje błąd i… nic nie robi. Albo próbuje ponownie w nieskończoność, zaśmiecając kolejkę.

Prawidłowe podejście: Wdrożenie dead letter queue (DLQ) – osobnej kolejki dla eventów, które nie udało się przetworzyć po kilku próbach. Należy też określić politykę ponawiania: liczba prób, backoff (np. wykładniczy), timeouty. Dodatkowo warto monitorować DLQ i alertować, gdy liczba nieudanych eventów przekracza próg.

Przykład z życia: Sklep z elektroniką stracił 5% zamówień, bo eventy „payment.success” nie docierały do systemu wysyłkowego. Przyczyną był błąd walidacji danych (nieprawidłowy format adresu). Eventy lądowały w black hole – logowały się, ale nie trafiały do DLQ. Dopiero po dodaniu DLQ i monitoringu wykryto problem i naprawiono walidację.

Konsekwencje: Utrata zamówień, niezrealizowane wysyłki, spadek reputacji.

Błąd #3: Niewłaściwe zarządzanie kolejnością eventów

W e-commerce często zdarzenia muszą być przetwarzane w określonej kolejności. Na przykład: najpierw „payment.pending”, potem „payment.success”, a dopiero potem „order.shipped”. Jeśli kolejność zostanie zachwiana, system może wysłać przesyłkę przed potwierdzeniem płatności.

Architektura event-driven domyślnie nie gwarantuje kolejności – zwłaszcza gdy używamy wielu partycji. Rozwiązaniem jest stosowanie key-based partitioning (np. identyfikator zamówienia jako klucz partycji), aby wszystkie eventy dla danego zamówienia trafiały do tej samej partycji i były przetwarzane sekwencyjnie. Alternatywnie można używać dedykowanych narzędzi do event sourcing lub sagas.

Przykład z życia: Klient wdrożył Kafkę dla usługi płatności. Użyli domyślnego hashowania klucza, ale kluczem był UUID zamówienia, co rozrzucało eventy po wszystkich partycjach. W efekcie przetwarzanie równoległe powodowało, że czasami „order.shipped” był przetwarzany przed „payment.success”. Na szczęście mieli zabezpieczenia w logice biznesowej, ale opóźnienia były znaczne.

Konsekwencje: Błędy logiczne, problemy z transakcjami, trudne do debugowania.

Podsumowanie: Jak uniknąć tych błędów?

Architektura event-driven to potężne narzędzie, ale wymaga przemyślanego projektu. Oto trzy kluczowe zasady:

  1. Wzbogacaj eventy, nie wywołuj synchronicznie – jeśli handler potrzebuje danych, dodaj je do eventu lub użyj widoków lokalnych.
  2. Zaimplementuj DLQ i monitoring – nieudane eventy nie mogą ginąć. Bez DLQ tracisz kontrolę.
  3. Zadbaj o kolejność – używaj odpowiedniego klucza partycji, a jeśli potrzebujesz sekwencyjności, rozważ sagas lub event sourcing.

W JurskiTech regularnie pomagamy firmom przejść na architekturę event-driven lub poprawić istniejące implementacje. Często okazuje się, że problem nie leży w samym narzędziu, ale w projekcie. Jeśli rozwijasz e-commerce i czujesz, że architektura zaczyna Cię ograniczać – warto spojrzeć na nią krytycznie. Event-driven może być zbawieniem, ale tylko jeśli zrobisz to dobrze.

Tagi:

Zostaw odpowiedź

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *