{"id":1839,"date":"2026-05-08T11:00:53","date_gmt":"2026-05-08T11:00:53","guid":{"rendered":"https:\/\/news.jurskitech.pl\/blog\/uncategorized\/3-bledy-w-implementacji-event-driven-architecture-w-saas\/"},"modified":"2026-05-08T11:00:53","modified_gmt":"2026-05-08T11:00:53","slug":"3-bledy-w-implementacji-event-driven-architecture-w-saas","status":"publish","type":"post","link":"https:\/\/news.jurskitech.pl\/blog\/warto-wiedziec\/3-bledy-w-implementacji-event-driven-architecture-w-saas\/","title":{"rendered":"3 b\u0142\u0119dy w implementacji Event Driven Architecture w SaaS"},"content":{"rendered":"<h2 id=\"wstp\">Wst\u0119p<\/h2>\n<p>Event Driven Architecture (EDA) obiecuje elastyczno\u015b\u0107, skalowalno\u015b\u0107 i lu\u017ane powi\u0105zania mi\u0119dzy serwisami. Brzmi jak idea\u0142 dla ka\u017cdego SaaS, kt\u00f3ry dynamicznie ro\u015bnie. Jednak z mojej praktyki wynika, \u017ce w wi\u0119kszo\u015bci wdro\u017ce\u0144 EDA ko\u0144czy si\u0119\u2026 gorzej ni\u017c monolit. Nie dlatego, \u017ce idea jest z\u0142a, ale dlatego, \u017ce implementacja kuleje. Klienci przychodz\u0105 do nas po audycie z typowymi objawami: system dzia\u0142a wolno, eventy si\u0119 gubi\u0105, trudno debugowa\u0107, a koszty chmury rosn\u0105 w spos\u00f3b niekontrolowany. W tym artykule poka\u017c\u0119 trzy kluczowe b\u0142\u0119dy, kt\u00f3re pope\u0142niaj\u0105 nawet do\u015bwiadczone zespo\u0142y, i jak ich unikn\u0105\u0107.<\/p>\n<h2 id=\"1brakstrategiiobsugibdwweventloop\">1. Brak strategii obs\u0142ugi b\u0142\u0119d\u00f3w w event loop<\/h2>\n<p>Pierwszy b\u0142\u0105d to traktowanie systemu eventowego jak czarnej skrzynki. Zespo\u0142y cz\u0119sto zak\u0142adaj\u0105, \u017ce skoro event zosta\u0142 wys\u0142any, to na pewno zostanie przetworzony. A potem zdarza si\u0119 katastrofa: awaria brokera, tymczasowa niedost\u0119pno\u015b\u0107 konsumenta, b\u0142\u0105d deserializacji. I co wtedy? Najcz\u0119\u015bciej event ginie w czelu\u015bciach log\u00f3w, a klient traci zam\u00f3wienie, dane lub sp\u00f3jno\u015b\u0107.<\/p>\n<p>Przyk\u0142ad z \u017cycia: Klient (firma SaaS z bran\u017cy e-commerce) wdro\u017cy\u0142 eventy dla aktualizacji stan\u00f3w magazynowych. Przy wysy\u0142ce zam\u00f3wienia system wysy\u0142a\u0142 event do zarezerwowania towaru. Broker \u2013 RabbitMQ \u2013 z jakiego\u015b powodu zwr\u00f3ci\u0142 b\u0142\u0105d, ale aplikacja nie mia\u0142a \u017cadnej procedury retry. Rezultat: zam\u00f3wienie przesz\u0142o, ale stan magazynowy nie zosta\u0142 zaktualizowany. Magazyn wys\u0142a\u0142 produkt, kt\u00f3ry fizycznie nie istnia\u0142. Klient musia\u0142 r\u0119cznie anulowa\u0107 setki zam\u00f3wie\u0144.<\/p>\n<p>Jak to zrobi\u0107 dobrze? Ka\u017cdy event powinien mie\u0107 mechanizm powt\u00f3rek (retry) z backoffem, a po wyczerpaniu pr\u00f3b \u2013 trafi\u0107 do Dead Letter Queue (DLQ). Nawet je\u015bli brzmi to jak dodatkowa praca, to w\u0142a\u015bnie ta warstwa ratuje biznes. W praktyce warto te\u017c monitorowa\u0107 wiek event\u00f3w w DLQ i alertowa\u0107, je\u015bli zaczynaj\u0105 si\u0119 starze\u0107.<\/p>\n<h2 id=\"2niedopasowaniesemantykieventwdokontekstubiznesowego\">2. Niedopasowanie semantyki event\u00f3w do kontekstu biznesowego<\/h2>\n<p>Drugi b\u0142\u0105d to projektowanie event\u00f3w wok\u00f3\u0142 struktur danych z bazy, a nie wok\u00f3\u0142 zdarze\u0144 biznesowych. Cz\u0119sto widz\u0119 eventy takie jak <code>UserUpdated<\/code>, <code>OrderModified<\/code> czy <code>ProductChanged<\/code>. To s\u0105 eventy techniczne, kt\u00f3re m\u00f3wi\u0105: \u201eco\u015b si\u0119 zmieni\u0142o w tabeli\u201d. Ale nie m\u00f3wi\u0105, co si\u0119 sta\u0142o w biznesie. A to ma kluczowe znaczenie dla odbiorc\u00f3w.<\/p>\n<p>Przyk\u0142ad: W jednym SaaS do zarz\u0105dzania subskrypcjami system wysy\u0142a\u0142 event <code>SubscriptionUpdated<\/code> za ka\u017cdym razem, gdy zmienia\u0142o si\u0119 pole w bazie. Odbiorcy (np. serwis billingowy czy system dost\u0119pu) nie wiedzieli, czy chodzi o przed\u0142u\u017cenie, anulacj\u0119, czy downgrade. Ka\u017cdy odbiorca musia\u0142 parsowa\u0107 JSON i domy\u015bla\u0107 si\u0119 intencji. Efekt? B\u0142\u0119dy w naliczaniu op\u0142at, niekonsystencje, a developerzy sp\u0119dzali godziny na debugowaniu.<\/p>\n<p>Rozwi\u0105zanie: Zamiast <code>SubscriptionUpdated<\/code> podziel na <code>SubscriptionStarted<\/code>, <code>SubscriptionCanceled<\/code>, <code>SubscriptionDowngraded<\/code>, <code>SubscriptionPaymentFailed<\/code>. Ka\u017cdy z tych event\u00f3w ma jasne znaczenie biznesowe i zawiera tylko te dane, kt\u00f3re s\u0105 potrzebne. Odbiorcy nie musz\u0105 analizowa\u0107 r\u00f3\u017cnic \u2013 dostaj\u0105 gotow\u0105 informacj\u0119. To pozornie drobna zmiana, ale redukuje b\u0142\u0119dy i czas developmentu.<\/p>\n<p>Dodatkowo unikaj nadmiernego rozrastania si\u0119 event\u00f3w: nie dodawaj do eventu wszystkich p\u00f3l z bazy, tylko to, co jest konieczne dla odbiorc\u00f3w. To zmniejsza rozmiar wiadomo\u015bci, obci\u0105\u017cenie sieci i u\u0142atwia ewolucj\u0119 schemat\u00f3w.<\/p>\n<h2 id=\"3brakcelowaniawskalowalnokonsumentw\">3. Brak celowania w skalowalno\u015b\u0107 konsument\u00f3w<\/h2>\n<p>Trzeci b\u0142\u0105d to projektowanie konsument\u00f3w event\u00f3w tak, jakby by\u0142y monolitycznymi odbiornikami. Cz\u0119sto widz\u0119 aplikacj\u0119, kt\u00f3ra subskrybuje eventy z kilku \u017ar\u00f3de\u0142 i przetwarza je w jednym procesie. Gdy ro\u015bnie liczba event\u00f3w, konsument staje si\u0119 w\u0105skim gard\u0142em, a kolejka event\u00f3w ro\u015bnie. Zamiast skalowa\u0107 poziomo (dodaj\u0105c wi\u0119cej instancji konsumenta), zesp\u00f3\u0142 pr\u00f3buje optymalizowa\u0107 jednow\u0105tkowy kod, co nie przynosi efektu.<\/p>\n<p>Przyk\u0142ad: Firma z bran\u017cy fintech mia\u0142a system rekomendacji, kt\u00f3ry nas\u0142uchiwa\u0142 event\u00f3w z kilku mikroserwis\u00f3w. Konsument by\u0142 jednym procesem Node.js. Gdy w black friday ilo\u015b\u0107 event\u00f3w wzros\u0142a stukrotnie, proces nie nad\u0105\u017ca\u0142, eventy zacz\u0119\u0142y timeoutowa\u0107, a broker straci\u0142 cz\u0119\u015b\u0107 wiadomo\u015bci. Klient straci\u0142 dane o zakupach, a rekomendacje na stronie g\u0142\u00f3wnej przesta\u0142y dzia\u0142a\u0107.<\/p>\n<p>Jak to zrobi\u0107 dobrze? Konsument powinien by\u0107 bezstanowy i skalowalny horyzontalnie. U\u017cyj wzorca \u201ecompeting consumers\u201d \u2013 wiele instancji tego samego serwisu czyta z tej samej kolejki, ka\u017cda przetwarza inne eventy. Pami\u0119taj te\u017c o idempotentno\u015bci: ka\u017cdy event powinien by\u0107 bezpieczny do ponownego przetworzenia. Nawet je\u015bli konsument przetworzy go dwa razy (np. po restarcie), system musi pozosta\u0107 sp\u00f3jny. Najprostsze: sprawdzaj, czy event ju\u017c zosta\u0142 obs\u0142u\u017cony (np. po ID eventu) lub zapewnij operacje idempotentne (np. zapis do bazy z operacj\u0105 UPSERT).<\/p>\n<h2 id=\"podsumowanie\">Podsumowanie<\/h2>\n<p>Event Driven Architecture to pot\u0119\u017cne narz\u0119dzie, ale wymaga dyscypliny. Prawdziwym wyzwaniem nie s\u0105 same eventy, tylko projektowanie systemu wok\u00f3\u0142 nich. Unikniesz kosztownych b\u0142\u0119d\u00f3w, je\u015bli:<\/p>\n<ul>\n<li>Zadbasz o obs\u0142ug\u0119 b\u0142\u0119d\u00f3w i Dead Letter Queue.<\/li>\n<li>Zaprojektujesz eventy wok\u00f3\u0142 zdarze\u0144 biznesowych, a nie zmian w bazie.<\/li>\n<li>Uczynisz konsument\u00f3w bezstanowymi i skalowalnymi horyzontalnie.<\/li>\n<\/ul>\n<p>Z mojego do\u015bwiadczenia: firmom, kt\u00f3re wdra\u017caj\u0105 te zasady, udaje si\u0119 skalowa\u0107 SaaS bez utraty kontroli nad kosztami i jako\u015bci\u0105. Je\u015bli Tw\u00f3j system oparty na eventach zaczyna sprawia\u0107 b\u00f3l \u2013 warto zrobi\u0107 audyt pod k\u0105tem tych trzech punkt\u00f3w. Cz\u0119sto okazuje si\u0119, \u017ce wystarczy kilka zmian, by tchn\u0105\u0107 nowe \u017cycie w architektur\u0119.<\/p>\n<p>A jakie b\u0142\u0119dy Ty najcz\u0119\u015bciej widzisz w implementacji EDA? Podziel si\u0119 w komentarzu \u2013 ch\u0119tnie przedyskutujemy.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wst\u0119p Event Driven Architecture (EDA) obiecuje elastyczno\u015b\u0107, skalowalno\u015b\u0107 i lu\u017ane powi\u0105zania mi\u0119dzy serwisami. Brzmi jak idea\u0142 dla ka\u017cdego SaaS, kt\u00f3ry dynamicznie ro\u015bnie. Jednak z mojej praktyki wynika, \u017ce w wi\u0119kszo\u015bci wdro\u017ce\u0144 EDA ko\u0144czy si\u0119\u2026 gorzej ni\u017c monolit. Nie dlatego, \u017ce idea jest z\u0142a, ale dlatego, \u017ce implementacja kuleje. Klienci przychodz\u0105 do nas po audycie z<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[585,584,94,24],"class_list":["post-1839","post","type-post","status-publish","format-standard","hentry","category-warto-wiedziec","tag-bledy-implementacyjne","tag-event-driven-architecture","tag-saas","tag-skalowalnosc"],"_links":{"self":[{"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/posts\/1839","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/comments?post=1839"}],"version-history":[{"count":0,"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/posts\/1839\/revisions"}],"wp:attachment":[{"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/media?parent=1839"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/categories?post=1839"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/tags?post=1839"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}