Event Sourcing w Javie

Odpowiedz Nowy wątek
tk
2020-09-14 15:08
tk

Rejestracja: 8 lat temu

Ostatnio: 4 dni temu

0

Witajcie,

Chciałbym stworzyć pewien system w Javie oparty na mikrousługach oraz DDD. W związku z tym mam kilka pytań dotyczących Event Sourcingu:

  1. Jakiej technologii najlepiej użyć do Event Sourcingu? Które z dostępnych rozwiązań jest waszym zdaniem najlepsze i jakie w ogóle są?

  2. Które jest najbardziej popularne w systemach napisanych w Javie? Rozwiązanie nie musi być przeznaczone tylko dla aplikacji pisanych w Javie. Bardziej chodzi mi o to z jaką technologią Javowcy się najczęściej spotykają podczas prac z mikrousługami i Event Sourcingiem.

  3. Czy znacie rozwiązania dzięki którym można w Event Storze umieścić zdarzenia w taki sposób aby ich kolejność podczas odtwarzania stanu agregatu ze zdarzeń była inna niż kolejność faktycznego umieszczenia zdarzeń w Event Storze? Chodzi mi o to, że chciałbym mieć aplikacje serwerową i aplikacje klienckie, które z założenia byłyby zdolne do pracy w trybie offline. W sytuacji gdyby jeden użytkownik korzystający z aplikacji offline zmienił dane pewnego dnia powiedzmy o godzinie 18:00 a drugi (korzystający z aplikacji online) zmieniłby te same dane o godzinie 19:00 to podczas synchronizacji o godzinie 20:00 (dane są synchronizowane przez aplikacje działającą wcześniej offline podczas przejścia w stan online) chciałbym mieć zdarzenia poukładane chronologicznie (użytkownik pracujący offline dokonał zmiany wcześniej niż użytkownik pracujący online ale to ten, który pracował online miał dostęp do serwera i z punktu widzenia serwera dokonał zmian wcześniej).

Pytanie trzecie jest bardziej opcjonalne: podczas odpowiadania na ten post nie należy sugerować rozwiązań pod trzecie kryterium.

Pozostało 580 znaków

2020-09-14 15:24

Rejestracja: 1 rok temu

Ostatnio: 2 minuty temu

Lokalizacja: Silesia

1

Ad. 1. Chodzi Ci o broker wiadomości? Kafka lub RabbitMQ
Ad. 2. Nie rozumiem pytania
Ad. 3. Synchronizacja stanu bazy po offline to strasznie skomplikiwany problem. W przypadku ogolnym nierozwiązywalny


Niektórzy by się kłócili https://dzone.com/articles/ap[...]fka-is-not-for-event-sourcing i pewnie Vaughn Vernon też by sie sprzeciwil - karsa 2020-09-14 15:32

Pozostało 580 znaków

2020-09-14 15:34

Rejestracja: 6 lat temu

Ostatnio: 53 minuty temu

0

a czy na pewno jest Ci to potrzebne?
https://eventstore.com/use-cases/
https://axoniq.io/blog-overvi[...]event-sourcing-frans-van-buul

edytowany 3x, ostatnio: karsa, 2020-09-14 16:26
Jemu pewnie nie, mi też nie ale w sumie to bym poczytał :D - OtoKamil 2020-09-14 16:05
Jeden z częstych przykładów na use case to shopping cart - karsa 2020-09-14 16:28

Pozostało 580 znaków

2020-09-14 17:30
Moderator

Rejestracja: 16 lat temu

Ostatnio: 1 minuta temu

1

Ta opcja 3 brzmi bardzo źle, bo oznacza że można by bardzo łatwo zaburzyć spójność danych i generalnie narobić cudów w systemie, skoro pozwalasz na "modyfikowanie historii", szczególnie z poziomu jakiejś aplikacji klienckiej. Nie wiem co ten system ma robić, ale mocno bym się nad tym zastanowił.


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

tk
2020-09-14 18:25
tk

Rejestracja: 8 lat temu

Ostatnio: 4 dni temu

0
KamilAdam napisał(a):

Ad. 1. Chodzi Ci o broker wiadomości? Kafka lub RabbitMQ

Chodzi mi o to aby mógł odtworzyć stan obiektów na podstawie zdarzeń, które zaszły w systemie. Jeżeli więc użytkownik:

  1. Zarejestruje się w systemie i poda swój adres e-mail. Niech to będzie adres X
  2. Później zmieni swój adres e-mail z X na Y
  3. Później zmieni swój adres e-mail z Y na Z

To ja:

  1. Zapiszę gdzieś informację o tym, że doszło do zarejestrowania użytkownika z adresem e-mail X
  2. Zapiszę gdzieś informację o tym, że użytkownik zmienił adres e-mail z X na Y
  3. Zapiszę gdzieś informację o tym, że użytkownik zmienił adres e-mail z Y na Z
  4. Jak trzeba będzie ustalić jaki jest obecny adres e-mail użytkownika to przeczytam wszystkie powyższe zdarzenia i będę wiedział, że aktualny adres e-mail to Z.

Poczytałem trochę, że Kafka może sprostać tym oczekiwaniom ponieważ w Kafce można zapisać sekwencje zdarzeń i ją później przeczytać od początku do końca. Jednak spotkałem się też z krytyką takiego zastosowania i w sumie nie wiem jak to jest (informacje krytyczne mogą nie być już aktualne).

Co do Rabbita to mam trochę większe wątpliwości czy to się do tego nadaje. Nie używałem tego ale kojarzy mi się to bardziej z przesyłaniem komunikatów bez gwarancji, że zostanie zachowana kolejność ich dostarczania no i nie wiem czy można sobie przeczytać od tak cała historie komunikatów od samego początku czy bardziej działa to na zasadzie "masz dostęp do komunikatu, którego jeszcze nie odebrałeś a nie do tych, które kiedyś zostały już dostarczone".

Ad. 2. Nie rozumiem pytania

Załóżmy hipotetycznie, że technologie RabbitMQ, Kafka i Axon spełniają wymagania i można to wykorzystać do Event Sourcingu. Jeżeli np. w projektach tworzonych za pomocą języka Java dominuje technologia Axon (np. w 8 na 10 Javowych projektach korzysta się z Axona, w 1 na 10 z Rabbita i w 1 na 10 z Kafki) to odpowiedź na moje pytanie brzmi "Axon jest najpopularniejsza technologią stosowana do Event Sourcingu w Javowych projektach". Gdyby to RabbitMQ był najbardziej popularną technologią w Javowych projektach to wtedy odpowiedź na moje pytanie brzmi "RabbitMQ jest najpopularniejsza technologią stosowana do Event Sourcingu w Javowych projektach". Sam RabbitMQ nie jest wtedy technologią ściśle powiązaną z Javą tylko technologią, z której mogą korzystać również programiści innych języków no ale jeżeli akurat Javowcy tego zazwyczaj używają to taka byłaby odpowiedź.

Ad. 3. Synchronizacja stanu bazy po offline to strasznie skomplikiwany problem. W przypadku ogolnym nierozwiązywalny

No właśnie odnoszę wrażenie, że przy zastosowaniu Event Sourcingu problem mógłby się znacznie uprościć (tak mi się przynajmniej wydaje na chwilę obecną :))

karsa napisał(a):

a czy na pewno jest Ci to potrzebne?

Jeszcze nie wiem :) Generalnie to chciałem poszerzyć nieco horyzonty więc chętnie wypróbuje :)

Shalom napisał(a):

Ta opcja 3 brzmi bardzo źle, bo oznacza że można by bardzo łatwo zaburzyć spójność danych i generalnie narobić cudów w systemie, skoro pozwalasz na "modyfikowanie historii", szczególnie z poziomu jakiejś aplikacji klienckiej. Nie wiem co ten system ma robić, ale mocno bym się nad tym zastanowił.

Rozumiem Twoje obawy. Jednak jeżeli chodzi o aplikacje kliencką to raczej chciałbym to zorganizować w ten sposób żeby taka aplikacja mogła synchronizować zdarzenia z serwerem tylko wtedy kiedy użytkownik ma odpowiednie uprawnienia do tego. Zakładam tutaj, że albo użytkownikiem nie będzie przypadkowa osoba albo sytuacje, w której użytkownik nie będzie miał możliwości synchronizowania zdarzeń, które mogą mieć wpływ na innych użytkowników.

Pokaż pozostałe 2 komentarze
Zmiany danych users to według mnie zły przykład. Raczej nie chcesz tego w żaden sposób dystrybuować bo dochodzi kontekst gdpr. Zamiast nad event sourcingiem to skupilbym się na event driven, bez myślenia o sourcingu. - karsa 2020-09-14 18:40
Ile zespołów będzie pracować przy tym systemie? - karsa 2020-09-14 18:41
@karsa: na chwile obecną jeden zespół jednoosobowy :) Projekt póki co hobbystyczny. Mam dostęp do serwera, na którym mogę uruchomić Docker-a. System ma na chwilę obecną działać na moje własne potrzeby a w późniejszym czasie się zobaczy czy nadaje się to do czegoś więcej. Mimo wszystko nie chciałbym abyś podchodził do tego jak do małego projektu bo jednym z celów jest poszerzenie horyzontów i w miarę możliwości wolałbym korzystać z narzędzi, które są stosowane w poważnych systemach. Po prostu nie mam doświadczenia ani z DDD ani z mikrousługami wiec chce się temu przyjrzeć. - tk 2020-09-14 19:17
Microservices w jedną osobę to dość specyficzny pomysł. DDD możesz bawić się w jednej appce. - karsa 2020-09-14 19:30
@karsa: zdaję sobie z tego sprawę :) - tk 2020-09-14 19:31

Pozostało 580 znaków

2020-09-14 19:00

Rejestracja: 2 lata temu

Ostatnio: 27 minut temu

1

Wydaje mi się, że algorytmy biznesowe offline a event sourcing to jest inna bajka - choć w sposób oczywisty widać podobieństwa
Zarazem, o ile algorytmy offline to istotna część realnej pracy w realnym życiu biznesowym, to mocno niedowartościowane teoretycznie.

KamilAdam napisał(a):

Ad. 2. Nie rozumiem pytania

ja też

Ad. 3. Synchronizacja stanu bazy po offline to strasznie skomplikiwany problem. W przypadku ogolnym nierozwiązywalny

Intuicyjnie mi się wydaje, że lekarstwo jest w projekcie dziedzinowym, aby rzeczy ulegały "samonaprawieniu", czy "samosynchronizacji" (idealnie, by nie psuły się wcale)
W każdym razie bardzo daleko od myślenia "weźmy technologię X" i nam załatwi

edytowany 1x, ostatnio: AnyKtokolwiek, 2020-09-14 19:01
Ujmę trochę prościej drugie pytanie: "jaka technologia do Event Sourcingu jest stosowana najczęściej przez Javowców?" - mam nadzieję, że teraz wszystko jasne :) - tk 2020-09-14 19:24

Pozostało 580 znaków

2020-09-14 19:35

Rejestracja: 6 lat temu

Ostatnio: 53 minuty temu

2

Może Cię zainteresuje
https://github.com/kbastani/spring-cloud-event-sourcing-example

Chociaż tam był jakiś issue brzydki gdzies... edit.: o ten https://github.com/kbastani/e[...]croservices-example/issues/28

edytowany 1x, ostatnio: karsa, 2020-09-14 20:48
Zainteresowało :) - tk 2020-09-14 19:37
o ten issue mi chodziło https://github.com/kbastani/e[...]croservices-example/issues/28 , oczekiwalbym nieco wiecej po kbastani. Koleś ewangelizuje te wszystkie buzzwordy albo robi prezentacje na ten temat jak we wspomnianym issue i taka lipa - karsa 2020-09-14 20:49
Bardzo fajny thread, paru mocnych zawodników się wypowiedziało, sporo się można nauczyć. Autor rzeczywiście się trochę zamieszał. - Charles_Ray 2020-09-14 21:23
Najlepsze, że kbastani i Richardson mieli chyba o tym prezke X lat wcześniej lol - karsa 2020-09-14 21:36
@karsa: dzięki :) - tk 2020-09-14 21:39

Pozostało 580 znaków

2020-09-15 15:35

Rejestracja: 4 lata temu

Ostatnio: 6 minut temu

Lokalizacja: U krasnoludów - pod górą

2
Shalom napisał(a):

Ta opcja 3 brzmi bardzo źle, bo oznacza że można by bardzo łatwo zaburzyć spójność danych i generalnie narobić cudów w systemie, skoro pozwalasz na "modyfikowanie historii", szczególnie z poziomu jakiejś aplikacji klienckiej. Nie wiem co ten system ma robić, ale mocno bym się nad tym zastanowił.

To akurat nie jest żaden problem. Jeśli masz cały system oparty o event sourcing to manipulowanie historią jest oczywiste i (prawie) proste.

Miliony developerów korzystających z gita widzi codziennie, że to działa.
Każdy głupi sieciowy RTS,FPS musi sobie też z tym radzić (o ile nie chcemy aby gracze mieli 2 sekundowy lag).

Problem jest tylko wtedy kiedy częśc systemu nie bazuje na eventach....

A rozwiązaniem jest jak w gicie - najlepiej w evencie podawać do której wersji obiektu się odnosi. Wtedy, w event handlerze można zauważyć, że ktoś nam namieszal i nie zgadza się oczekiwany numer wersji obiektu - można napisać jakiś "conflict solver",

Czasem konflkt będzie trywialny - jeśli inkrementujesz,sumujesz licznik to nie ma problemu.
Czasem będzie trudny - jeden użytkownik dodaje opis do produktu, a drugi go usuwa - rozwiązanie zależy od wymagań biznesowych.

Najbliżej gotowca do CQRS jest dla mnie jest https://www.lagomframework.co[...]entation/1.6.x/java/Home.html.
Ale nie wiem na ile trudno by tam zrobić offline handling. Takie rzeczy robiłem dawno temu "ręcznie" (zanim dowiedziałem się, że to jest event sourcing).


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000, 2020-09-15 15:36
Pokaż pozostałe 6 komentarzy
@Shalom: nie do końca - zawsze mamy wszystkie zdarzenia, nic nie znika, więc o konflikcie się dowiemy. Oczywiście to od biznesu zależy czy i na ile dopuszczamy takie offline/online. W totolotku by się nie sprawdziło. - jarekr000000 2020-09-15 15:43
Przykład z ubezpieczeń - to agenci chodzący po domach z offline bazą klientów i dorzucający dane do systremu CRM (tzw. mutacje polis) po synchronizacji. Raz na rok jest konflikt, bo klient coś podpisał w domu, a potem zadzwonił, że się rozmyslił... - btw. zresztą obecnie w dobie internetu komórkowego - to już bardzo rzadki przypadek. - jarekr000000 2020-09-15 15:46
Git zakłada szeregowanie zgodne z pushem do remote, a nie zgodne z commitem do lokalnego repo. nie zmieniałeś nigdy historii w gicie? :-) - jarekr000000 2020-09-15 15:59
Force push na mastera na remote? Codziennie rano tak robie, zaraz po dropie na produkcyjnej bazie ;) Lepsze na podniesienie ciśnienia niż kawa - Shalom 2020-09-15 16:04
@Shalom git filter-branch a potem push na mastera :-) - jarekr000000 2020-09-15 16:14

Pozostało 580 znaków

2020-09-15 18:21

Rejestracja: 15 lat temu

Ostatnio: 3 minuty temu

0

Git przy commicie zapisuje pełne snapshoty, a nie kompaktowe eventy (diffy). Zachodzi oczywiście deduplikacja danych, by repo gitowe nie zajmowało kosmicznych ilości miejsca na dysku. Diffy w gicie są liczone na żądanie - każdy commit to pełny snapshot, więc jak chcemy porównać dwa commity to wyciągamy te dwa snapshoty i porównujemy. Wadą podejścia gitowego jest to, że czasami silnik do obliczania różnic się myli, np gdy w jednym commicie zarówno zmienimy trochę zawartość pliku jak i jego nazwę to git może nie załapać, że to edycja jednego pliku i zamiast modyfikacji pokaże usunięcie starego pliku i dodanie nowego. SVNy, CVSy i inne starożytne VCSy chyba nie mają takiego problemu. Coś za coś.

Jeśli chodzi o automatyczne rozwiązywanie konfliktów przy rozbieżnościach historii edycji to są do tego specjalne struktury danych (dla stosunkowo wąskiego grona przypadków): https://en.wikipedia.org/wiki[...]ict-free_replicated_data_type

Edycja wycinka historii to moim zdaniem kiepski pomysł, bo przy edycji eventu o timestampie T trzeba:

  • wyrzucić wszystkie snapshoty z timestampem >= T
  • cofnąć się do ostatniego pozostałego snapshotu
  • odegrać od nowa (tzn nanieść zmiany w bazie odpowiadające zawartości eventu) wszystkie eventy o timestampie >= T

Można to porównać do edycji commitu gitowego. Jeśli edytujemy commit zrobiony 5000 commitów temu to trzeba przepisać te 5000 commitów, a to zajmuje czas.

W trakcie przepisywania historii (w sensie: odgrywania zedytowanej historii eventów na bazę danych do odczytu) cały system powinien dalej działać. Co więc robimy jeśli do końca przepisywania jeszcze daleko, a klienci chcą widzieć swoje dane (włączając najnowsze zmiany)? Może stawiamy dwie bazy i się między nimi przełączamy po przepisaniu historii?

Każdy głupi sieciowy RTS,FPS musi sobie też z tym radzić (o ile nie chcemy aby gracze mieli 2 sekundowy lag).

W przypadku gier nie ma potrzeby robienia merge'a. Każdy atrybut można traktować jako osobny plik, który się w całości nadpisuje, a nie merge'uje. Jeśli serwer np przeniesie gracza o wektor (3, 5) (bo tak sobie obliczył na podstawie jego poprzednich ruchów), a potem dostanie sygnał od niego, że naprawdę było (4, 4) to ten drugi sygnał wygrywa i tyle. Last write wins i po temacie.

Druga sprawa to to czy te silniki gier sieciowych robią jakąś skuteczną magię? Filmiki znalezione na szybko na YT zdają się temu przeczyć:

Symulowanie ruchów gracza przez serwer może się sprawdza dla małych lagów, ale przy dużych (np sekundy) mamy znaczny teleporting.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 3x, ostatnio: Wibowit, 2020-09-15 18:35
Pisanie gier w Kotlinie na silniku KorGE to dobry pomysł na poznanie języka? https://korge.org/ - sarmata 2020-09-15 18:53

Pozostało 580 znaków

2020-09-15 20:55

Rejestracja: 4 lata temu

Ostatnio: 6 minut temu

Lokalizacja: U krasnoludów - pod górą

1

W aplikacjach biznesowych masz zwykle niezależne strumienie eventów na każdy agregat (właśnie z powodów wydajnościowych/skalowania).
Dlatego raczej tysięcy eventów odgrywać nie musisz.

Co do gier - moja wiedza pochodzi sprzed 15 lat kiedy tematem się zajmowałem (robiłem gre, nawet za pieniądze - chociaż nic z tego nie wyszło na koniec). Dużo wtedy doczytałem, choć w kod żadnej sensownej AAA nie zaglądałem. Ta książka (o ile pamiętam, bo dużo tego kiedyś czytałem) https://helion.pl/ksiazki/per[...]om-3-dante-treglia,ppgvp3.htm
była moją inspiracją w temacie - choć niekoniecznie nazywało się to tam event sourcing (nie pamietam):

Generalnie bez jakiegoś event sourcingu trudno było w czasach internetu z pingiem 1s (20-15 lat temu) zrobić gre sieciową która nie będzie lagowała. RTS to najlepszy przykład - masz 200 jednostek na ekranie, 4 graczy - jedyne co możesz rozsyłać to eventy.
dzieją się wtedy zabawne sytuacje, bo może własnie strzeliłeś z jakiegos BFG... ale wg danych, które przeszły od innego gracza to twoja jednostka zginęła 50ms wcześniej.
Faktycznie w grach jest raczej globalny strumień eventów, a baza danych to kawałek pamięci... i wtedy masz dwie kopie (tak jak piszesz). Jedną z twoimi eventami - to leci na ekran. Drugą (safe), opóźnioną z eventami zatwierdznymi przez master (jeden z graczy zwykle pełni rolę master serwera). Jeśli dojdzie do konfliktu, to robi się klon safe i odtwarza eventy wg. kolejności u mastera.
Ważną rzeczą jest wykrywanie konfliktu - bo większość pomieszania zdarzeń nie wpływa na stan gry - wiec trzeba mieć jakiś checksum stanu gry (wpływają na niego twarde dane - ilość zywych jednostek itp), to że jakaś jednostka jest w nieco innym miejscu można zwykle olać. Jeśli konfliktów będzie dużo to fakycznie jest problem z permanentnym klonowaniem i odtwarzaniem z safe.
Na mniejszą skalę problem jest w grach FPS. To, że gracze lagują i przeskakują po ekranie to mały pikuś - problem jest jak dwóch graczy do siebie strzeli np, z rakiety - może być konflikt, kto zginął. A komuś fraga trzeba dać.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000, 2020-09-15 20:56
jak dwóch graczy do siebie strzeli np, z rakiety - może być konflikt, kto zginął - hmm, obaj? - Wibowit 2020-09-16 07:03
@jarekr000000: Co to jest aplikacja biznesowa? - PerlMonk 2020-09-16 07:22
Co to jest aplikacja biznesowa Dobre pytanie. Sam używam tego terminu a jakbym miał podać definicję to nie wiem. Strzelałbym że to na pewno nie gra, tylko zwykła standardowa aplikacja zamawiana przez biznes. Najpewniej działająca na serwerze, ale nie wiem czy to mieści się w ramach definicji - KamilAdam 2020-09-16 08:53
@KamilAdam: No właśnie. Spotkałem się z terminem "dane biznesowe" w aplikacji. Takie dane są przedmiotem przypadków użycia: login i e-mail to dane biznesowe, implementacja to inna sprawa. Aplikacja zawsze jest do czegoś używana, więc sama w sobie jest przedmiotem jakichś założeń biznesu. Może kwestia użycia... - PerlMonk 2020-09-16 09:12
@PerlMonk: słuszna uwaga. Jak dla mnie biznesowe jest przymiotnikiem o zerowym znaczeniu semantycznym. Wrzuciłem bez sensu. Taki koloryzator - o kolorze przezroczystym. Aplikacje biznesowe -> aplikacje, logika biznesowa -> logika. - jarekr000000 2020-09-16 09:23
@jarekr000000: logika biznesowa -> logika, ale jest jeszcze logika aplikacji - KamilAdam 2020-09-16 09:47

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0