Szkoda tylko że takie rzeczy 8 lat temu już można było przeczytać u ewangelistów, to pewnie na blogach inżynierów z 15 :P https://martinfowler.com/bliki/MonolithFirst.html
my używamy mirkoserwisów i jest dobrze. jak któryś się psuje to można je osobno restartować (a najczęściej to się restartują same, tzn. chmura restartuje padające kontenery), bez zarzynania całego systemu. kolejki i tak mamy do komunikacji ze światem zewnętrznym, więc dodatkowe wewnętrzne nie dokładają specjalnie złożoności. graphql nie mamy. za to widziałem próby zrobienia modułowych monolitów i to nie wypalało. te moduły to był pic na wodę, bo sprzężenia i cyklicznych zależności między modułami było mnóstwo. mikroserwisy (w miarę sensownie przemyślane) naturalnie prowadzą do loose coupling (bo tight coupling wymaga tutaj dużej nadbudówki), a w monolicie bardzo łatwo można zrobić sprzężenie (You wanted a banana but what you got was a gorilla holding the banana and the entire jungle. - Joe Armstrong, creator of Erlang progamming language.
). wyjątkiem są interfejsy restowe, włączając DTOsy. tutaj migracje mogą być problematyczne, jeśli nie stosujemy wersjonowania api.
@ehhhhh: no to może ci co tak mówią nie mają wystarczającego doświadczenia w obu podejściach :] ja mam doświadczenie zarówno w biznesowych niby-modularnych monolitach (2+ lata) jak i biznesowych mikroserwisach (8+ lat). @WeiXiao nawiązując do https://martinfowler.com/bliki/MonolithFirst.html to my mamy raczej opcję pierwszą, czyli Almost all the successful microservice stories have started with a monolith that got too big and was broken up
. odziedziczyliśmy architekturę opartą o 2 megaserwisy i kilka(naście?) pobocznych mikroserwisów i rozbiliśmy te 2 megaserwisy na kilkanaście małych + nowy frontend (tym razem react, a nie server-side liftweb). projektując te nowe mikroserwisy w zdecydowanej większości przypadków było tak, że stare wymagania biznesowe były już w jakiś sposób zaimplementowane w starych kobyłach, a nowe mikroserwisy implementowały mniej lub bardziej zmodyfikowane wymagania biznesowe, ale i tak wystarczająco podobne, by móc sensownie zaprojektować nową architekturę na bazie doświadczeń ze starej.
@Wibowit: kojarzysz patoarchitektów na yt, albo słuchasz ich podcastów na innych platformach? Jak opowiadają nie raz przyjeżdżają na zlecenie by pomóc opracować architekture i po analizach wychodzi im monolit lub ewentualnie monolit z 1-2 dodatkowymi wydzielonymi częściami jako osoba apka a zespół który miał to dalej robić zdziwiony "ale jak to monolit? My przecież chcieliśmy microserwisy."
@ehhhhh: nie kojarzę ich. jeśli nie lubią mikroserwisów to nie będą robić mikroserwisów. wiem, że u nas się sprawdziły. wiem też, że w sabre (w tym projekcie w którym pracowałem) modularny monolit de facto nie był modularny, bo zdecydowana większość kodu siedziała w dwóch silnie powiązanych modułach core
i common
i były też silne cykle zależności, tzn. wiele sytuacji typu kod z paczki A wołał paczkę B, paczka B wołała C, paczka C wołała A, itd i stąd porządne rozdzielenie tego na moduły było mało prawdopodobne. mój kolega z zespołu miał chyba kilka podejść po kilka tygodni każde do porządnego rozdzielenia na mikroserwisy, ale poległ w boju. ja byłem wtedy jeszcze mało zaawansowany, więc nie porywałem się na grube refaktory. mieliśmy bardzo duże problemy z wyciekiem pamięci i był bardzo ambitny cel redukcji restartów systemu. jak ja tam byłem to restart był codziennie, a ambitny plan był taki, żeby tych wycieków było na tyle mało, żeby restartować co tydzień. (pseudo)modularność tego monolitu pozwalała go uruchamiać w wielu instancjach, niektóre miały inne zadania, ale i tak zawsze była taka główna instancja zjadająca > 2/3 ogólnej pamięci, z największymi wyciekami pamięci i to od niej zależała stabilność systemu. było to ogólnie bardzo słabe. z drugiej strony, ten projekt to bardzo brązowy brownfield (starszy niż java :) tzn. zaczynał w c++, potem jak pojawiła się java to był przepisany do javy przez jakichś noobków podobno), stąd problemy są znacznie większe niż przy greenfieldowych monolitach. mikroserwisy mają to do siebie, że jak jakiś stanie się paskudny w utrzymaniu to zwykle znacznie łatwiej go przepisać od nowa niż jakiś moduł w monolicie super mocno sprzężony z innymi. ogólnie trzeba myśleć perspektywicznie, np. jeśli projekt będzie trwał dekady to moim zdaniem lepiej iść w mikroserwisy, bo łatwiej je kiedyś zaorać i zastąpić nowymi, ale z drugiej strony jeśli dopiero zaczynamy i niewiele wiemy co się dzieje w praktyce to projektowanie architektury mikroserwisów w takiej sytuacji to błądzenie jak dziecko we mgle. zamiast skrajnego podejścia typu 0 mikroserwisów albo 0 monolitów trzeba adaptować się do sytuacji.
@Wibowit: to nie ma tak że lubią czy nie lubią tylko tego czy dana architektura pasuje do wymagań systemu. Niestety ale w większości ludzie się rzucają na to bo widza tylko zalety ale nikt głośno nie mówi o wadach i potem właśnie m.in ci z podcastu są wynajmowani by ratowali pożar bo dobrali złą architekturę, projekt właśnie miał być oddany a zespól zrobił 20% projektu bo walczył dumnie z problemami architektury. Ja jestem zwolennikiem wydzielania tylko tego co rzeczywiście ma sens być osobnym bytem i widać to ewidentnie.
@ehhhhh: projekt właśnie miał być oddany a zespól zrobił 20% projektu bo walczył dumnie z problemami architektury.
- u nas nie ma fazy oddania. projekt trwa już chyba > 10 lat i nie ma planów, by kiedyś zakończyć jego rozwój, tzn. rynek się zmienia, regulacje się zmieniają, integracja z zewnętrznymi dostawcami czy odbiorcami danych też się zmienia, więc trzeba cały czas coś orać w systemie. Ja jestem zwolennikiem wydzielania tylko tego co rzeczywiście ma sens być osobnym bytem i widać to ewidentnie.
- to jest subiektywne, ale mając np. 30 mikroserwisów dołożenie kolejnego nie jest wielkim problemem. ci z podcastu są wynajmowani by ratowali pożar bo dobrali złą architekturę
- my mamy w miarę dobrą :) co do modularyzacji wewnątrz aplikacji to nawet niektóre nasze mikroserwisy są zmodularyzowane (tzn. nie są takie super mikro, tylko często takiej średniawej wielkości) i często ta modularyzacja nie ma dużego sensu czy zysku jak dla mnie. są jakieś tam moduły, ale silnie powiązane, więc w sumie po co? można by rozmawiać o modułach vs mikroserwisach bardzo długo. ja wolałbym zostać przy mikroserwisach. nie dość, że mikroserwis łatwiej przeorać (gruntowny refaktor, np. zmiana sposobu wstrzykiwania zależności, podbicie zależności, itd) to jeszcze mając mikroserwisy jestem trochę zabezpieczony przed tym, że mało krytyczna część systemu zarzyna cały system. jeśli jakiś mało krytyczny mikroserwis się wywali to niekoniecznie trzeba panikować i w środku nocy na on-callu rzeźbić system. system może działać częściowo, bez jakiegoś chwilowo popsutego mikroserwisu albo można ten mikroserwis restartować w kółko (prod support to ogarnie spokojnie) i poczekać do następnego dnia (albo i nawet tygodnia) roboczego.
@ehhhhh: pierwsza wersja nie miała mikroserwisów i była wydana w 6 tygodni (ze 3 lata przed tym jak projekt został przeniesiony z UK do PL): https://www.codemesh.io/codemesh2013/lance-walton
@S4t: Spójrz na to z jaśniejszej strony - to oznacza że 4p jest źródłem nauki dla ChatGPT! A teraz przewińmy szybko czas do przodu o jedno pokolenie (+/- 25 lat) i zróbmy z tego ekstrapolację w świecie gdzie ChatGPT zastąpił StackOverflow.
@Wibowit: jesli jestes w stanie zbudowac aplikacje w oparciu o mikroserwisy, to jestes rowniez w stanie zubowac identycznie decoupled moduly w strukturze monolitu. Jesli masz z tym problem to taki z ciebie programista jak z koziej d... traba.
@proximus-prime: ja jestem w stanie, ale czy kolegom z zespołu będzie się chciało utrzymywać porządne oddzielenie modułów? moje kiepskie doświadczenia z pseudomodularnością monolitów nie są moją winą. bardzo łatwo jest wprowadzić sprzężenie modułów w monolicie, więc to kusząca sprawa dla większości programistów jeśli można na tym zyskać sporo czasu podczas robienia aktualnego zadania. ponadto, w naszym przypadku, jak robiliśmy nowe mikroserwisy na bazie starych to nie kopiowaliśmy kodu, a analizowaliśmy architekturę starych megaserwisów (tzn. przerośniętych i zamotanych apek już nie zasługujących na miano mikroserwisu) i nowe wymagania biznesowe i tworzyliśmy sporo rzeczy od zera. stary zaplątany kod został zastąpiony przez nowe mikroserwisy i czasem taki manewr był znacznie prostszy niż naprostowanie starego kodu. no i przypomnę, że mikroserwisy oddzielają funkcjonalności też na poziomie zużycia zasobów i stabilności, tzn. jeden mikroserwis z przesadnym zużyciem zasobów czy losowo wykładający się nie położy całego systemu. od razu też widać, w którym miejscu jest problem (z grubsza, bo na poziomie mikroserwisu, ale to i tak lepiej niż badanie monolitu padającego na prodzie).
Z tego wpisu zrozumiałem tyle, że monolit czasem ma sens, a czasem nie. Tak samo z GQL, czasem jest sens go używać a czasem nie. Bardzo to wszystko odkrywcze i z sensem. Ile on tam lat potrzebował pracować, żeby dojść do tych prawd oświeconych?
Robić sensownie to nie jest wielkie osiągnięcie, ale luksus, na który tylko nieliczni mogą sobie pozwolić. Większość jest skazana na resume-driven development. ;)
Ja tylko wtrace, ze n+1 w GQL to wcale nie problem jak sie uzywa monad :> (co by nie straszyc monada, chodzi o zwracanie np. leniwego Query<Person>
zamiast Person
- no faktycznie nawet ludzi z 16letnim doswiadczeniem przerasta) albo innego rozwiazania dzieki, ktoremu serwer rozumie batchowanie - w Springu to pewnie bedzie jakas adnotacja.
@Wibowit: ... ale czy kolegom z zespołu będzie się chciało utrzymywać porządne oddzielenie modułów ...
- to za co biora pieniadze? za co bierze pieniadze lead? za co bierze pieniadze app-architect? zakladam ze rowniez code-review team robi odplatnie? ...że mikroserwisy oddzielają funkcjonalności też na poziomie zużycia zasobów i stabilności, ...
- modularny monolit rowniez to umozliwia. ...ale to i tak lepiej niż badanie monolitu padającego na prodzie ...
- decoupled modules w modularnym monolicie nie maja prawa wywalic ci calej aplikacji na prodzie.
Dobrze zrobiony modul w monolicie moze funkcjonowac zarowno jako "dopinana" paczka jak, osobny serwis jak i osobny folder ze swoim odzielnym namespace'em.
@proximus-prime: to za co biora pieniadze? za co bierze pieniadze lead? za co bierze pieniadze app-architect? zakladam ze rowniez code-review team robi odplatnie?
- za dowożenie funkcjonalności. o architekturze rozmawiamy głównie kiedy tworzymy nowe mikroserwisy albo powiązania między mikroserwisami. code review jest robione w większości po łebkach. ja staram się robić porządny przegląd kodu, ale to zajmuje czas, więc wydłuża dowożenie zadania (nie odrywam się natychmiast od swojej pracy, żeby przejrzeć czyjegoś pull requesta). jest jeszcze drugi kolega, który robi staranne code review (pracował kilka lat w projekcie, ale odchodzi za kilka dni). na standupie wyraźnie mówił o tym, że jak chce mieć porządne code review to daje pull requesta do mnie. reszta ludzi niespecjalnie chce poświęcać dużo czasu na review. obstawiam, że takie są realia w prawie wszystkich projektach. modularny monolit rowniez to umozliwia .... decoupled modules w modularnym monolicie nie maja prawa wywalic ci calej aplikacji na prodzie.
- na pewno nie jeśli chodzi jednoinstancyjny monolit. Dobrze zrobiony modul w monolicie moze funkcjonowac zarowno jako "dopinana" paczka jak, osobny serwis jak i osobny folder ze swoim odzielnym namespace'em.
- w sensie każdy moduł to osobny proces? to dobry pomysł, ale i tak niekoniecznie sprawia, że wymusza jakkolwiek dobrą architekturę. o ile dobrze pamiętam to w sabre ten legacy modularny monolit w którym rzeźbiłem odpalany był jako kilka procesów, ale sam kod w środku i tak był bardzo mocno sprzężony i poplątany. już pisałem o tym wcześniej. nie musisz mi tłumaczyć, że da się osiągnąć modularny monolit z cacy luźnymi powiązaniami między modułami. już to wiele lat temu rozkmniniałem. moje doświadczenia komercyjne są jednak takie, że modularny monolit się bardzo łatwo degraduje do big ball of mud, z którego nie da się wyjść bez długiego zastoju. oczywiście wszystko zależy od programistów w projekcie. gdzieś tam modularne monolity mogą być należycie pielęgnowane i utrzymywać ciągle dobrą architekturę. w ogólnym rozrachunku (patrząc na cały rynek ogólnie) jednak dyscyplina się nie skaluje. jeśli zadanie da się zrobić dużo szybciej i przyjemniej przez lekkie popsucie architektury to często tak się stanie. okazja czyni złodzieja. wracając do projektu nad którym pracuję w firmie. jest to projekt ponad 10-letni i nadal trzyma się dobrze. po przepisaniu tych starych 2 megaserwisów na kilkanaście nowych mikroserwisów jest łatwiej poogarniać co się dzieje. ile modularnych monolitów ponad 10-letnich ma nadal porządną modularyzację? jak łatwo w nich podbić zależności czy użyć nowych bibliotek czy frameworków (zwał jak zwał)?
@Wibowit: ...na pewno nie jeśli chodzi jednoinstancyjny monolit...
- na pewno tak jesli zbudowany jest tak jak wspomnialem wczesniej: "... modul w monolicie moze funkcjonowac zarowno jako "dopinana" paczka jak, osobny serwis jak i osobny folder ze swoim odzielnym namespace'em ..." (chociaz jesli miales na mysli zasoby fizyczne, to faktyznie tutaj sprawa jest o troche bardziej skomplikowana) ... w sensie każdy moduł to osobny proces?
- tak ...to dobry pomysł, ale i tak niekoniecznie sprawia, że wymusza jakkolwiek dobrą architekturę ...
- tak samo dobra/zla jak mikroserwisy. Z czasem tak samo mozesz zaorac zarowno modul jak i mikroserwis. Jak sie przylozysz zrobisz jak nalezy, jak nie to i z czolgu mozna zrobic lodz podwodna. ...jak łatwo w nich podbić zależności czy użyć nowych bibliotek czy frameworków...
- wlasnie dlatego kto ma chociaz odrobine oleju w glowie tworzy kod jako framework agnostic, ale faktycznie. latwiej/szybciej jest budowac z automatu TIR'a klientowi ktory potrzebuje hulajnoge zeby codziennie rano odwiedzac piekarnie za rogiem.
@proximus-prime: między mikroserwisami możesz wymieniać tylko dane (jsony czy cokolwiek innego, ale nie ma w nich kodu wykonywalnego). między modułami w jednym procesie możesz wymieniać obiekty, czyli coś co łączy dane z kodem i zależnościami. żeby mieć taki sam poziom izolacji między modułami co między mikroserwisami musiałbyś wymusić wymianę samych czystych danych, np. robiąc wewnętrznie komunikację na aktorach (może w erlangu tak się da wymusić, nie wiem) i wprowadzając ograniczenia na wiadomości. obiekt może kryć za sobą dowolną złożoność powiązań, a sama struktura danych jest niezależnym bytem samym w sobie i nie ma wprost powiązań z kodem. wlasnie dlatego kto ma chociaz odrobine oleju w glowie tworzy kod jako framework agnostic
- dependency hell nie unikniesz. mając mikroserwisy, każdy ma osobny mały dependency hell, zamiast jednego wielkiego dependency hell w monolicie. no chyba, że faktycznie izolujesz te moduły tak, że wymieniasz między nimi tylko dane (i wtedy każdy moduł może być osobnym procesem z osobnymi zależnościami czyli osobnym dependency hell), ale wtedy w zasadzie masz architekturę mikroserwisową w jednym monolitycznym projekcie. ponawiam pytanie: czy kojarzysz jakiegoś biznesowego monolita ponad 10-letniego, który dalej ma porządną modularyzację i nie utknął w starym stosie technologicznym?
@Wibowit: ... moduł może być osobnym procesem z osobnymi zależnościami czyli osobnym dependency hell ...
- bingo :D, czyz to nie sprawia iz tak zbudowany modul posiada zalety mikroserwisu? i jedyna różnica to brak narzutu na komunikację po rest api, bo wszystko jest wewnętrzne ...
- bingo po raz drugi :D - czyz to nie sprawia iz najwieksza zmora mikroserwisow staje sie nieistotna? A jesli jeszcze nie tylko aplikacje ale i moduly mozesz budowac z modulow, to Ci dopiero daje niezle mozliwosci. ... czy kojarzysz jakiegoś biznesowego monolita ponad 10-letniego, który dalej ma porządną modularyzację i nie utknął w starym stosie technologicznym ...
- jak zyje nigdy nie spotkalem sie z czyms takim. Powiem wiecej, widzialem kilka rzeczy, ale modularne
byly tylko z nazwy. Wszystko zalezy od tego kto tworzy definicje, potem kto ta definicje interpretuje, a na koncu kto ja implementuje. Dla mnie modul, to separowalna struktura, latwa w integracji w wiekszej calosci jako biblioteka, folder lub nawet jako separowalny mikroserwis w miare rozrostu monolitu. Czegos takiego poza projektami w ktorych biore udzial nigdy nie widzialem, ani 10, ani 5 ani 1 rocznego.
bingo :D, czyz to nie sprawia iz tak zbudowany modul posiada zalety mikroserwisu?
- i czy nie sprawia, że ma też wady? i jedyna różnica to brak narzutu na komunikację po rest api, bo wszystko jest wewnętrzne ... - bingo po raz drugi :D - czyz to nie sprawia iz najwieksza zmora mikroserwisow staje sie nieistotna?
- po chwili to wyedytowałem i usunąłem, bo jednak mając kilka procesów i tak te procesy muszą się jakoś komunikować, więc to nie jest wewnętrzne (tzn. wewnątrz jednego procesu). jak mają się komunikować moduły żyjące w osobnych procesach? jak zyje nigdy nie spotkalem sie z czyms takim. (...) Czegos takiego poza projektami w ktorych biore udzial nigdy nie widzialem, ani 10, ani 5 ani 1 rocznego.
- nie spotkałeś, ale brałeś udział? nie rozumiem :) p.s. jeszcze poruszę kolejną ważną sprawę jeśli chodzi o modularne monolity. zależności między modułami zwykle tworzą strukturę w drzewiastą lub mocno zbliżoną do drzewa. jest sobie główny moduł (lub kilka modułów) w korzeniu współdzielony przez wszystkie inne moduły. oranie tego głównego modułu oznacza często gęsto oranie całego projektu. w monolitach jest tendencja, żeby upychać dużo funkcjonalności do współdzielonych modułów. im bardziej rozrośnięte współdzielone moduły, tym gorsze możliwości punktowych (tzn. nierozlewających się na cały projekt) refaktorów i tym gorszy dependency hell (więcej wspólnego kodu = więcej problemów naraz przy podbijaniu zależności).
@Wibowit: ...jak mają się komunikować moduły żyjące w osobnych procesach...
ponownie problem uzywania pojec definiowanych w odmienny sposob jesli rozumiesz proces jako osobna instancje aplikacji to nie to mialem na mysli. Pojecia proces uzywalem w odniesieniu dowolnego niezaleznej struktury kodu (modulu) odpalanego w zaleznosci od potrzeby. ...jak mają się komunikować moduły żyjące w osobnych procesach...
w procesach ktore mialem na mysli tworzy sie w najprostszym ujeciu odpowiednie entry pointy w module. oranie tego głównego modułu oznacza często gęsto oranie całego projektu
- nie jesli np w aplikacjach webowych masz odpowiednio zbudowany routing, zanim udrzerzy do kontrolera, zbuduje wymagana i scisle okreslona sciezke budowy zaleznosci tylko i wylacznie w po galeziach ktore prowadza do wymaganej funkcjonalnosci. Oczywiscie jak sie uprzesz mozesz zamiast drzewa zbudowac amazonska dzungle, ale majac odrobine zdrowego rozsadku stwierdzasz w pewnym momencie ze chyba nadszedl czas zaczac budowe osobnego serwisu.
nie spotkałeś, ale brałeś udział? nie rozumiem
- to zacznij czytac ze zrozumieniem: "Dla mnie modul, to separowalna struktura, latwa w integracji w wiekszej calosci jako biblioteka, folder lub nawet jako separowalny mikroserwis w miare rozrostu monolitu." nastepnie "Czegos takiego poza projektami w ktorych biore udzial nigdy nie widzialem" - zdefinowalem modul a potem stwierdzilem ze czegos takiego nie widzialem, poza projektami w ktorych biore udzial.
Sorry, ale robi sie z tej dyskusji "bicie piany". Ide sobie cos wrzucic z Netflix'a.
@proximus-prime: ponownie problem uzywania pojec definiowanych w odmienny sposob jesli rozumiesz proces jako osobna instancje aplikacji to nie to mialem na mysli. Pojecia proces uzywalem w odniesieniu dowolnego niezaleznej struktury kodu (modulu) odpalanego w zaleznosci od potrzeby
- przy takich różnicach w pojęciach to się szybko nie dogadamy. ach, w sumie niespecjalnie chce mi się kontynuować temat, ale dzięki za rozmowę, trochę sobie pokminiłem. zdefinowalem modul a potem stwierdzilem ze czegos takiego nie widzialem, poza projektami w ktorych biore udzial
- czyli któryś z tych projektów w których brałeś udział ma ponad 10 lat i dalej jest porządnie zmodularyzowanym monolitem, który nie utknął w starym stosie technologicznym, tak?
@Wibowit: widzialem monolity z "modulami", ale "modularyzacja" zadnego z nich, niewazne czy 10, 5 czy 2 letniego, nie byla zgodna z definicja modulu ktora podalem. Z modularyzacji zgodna z definija ktora podalem spotkalem sie jedynie w projektach w ktorych aktualnie biore udzial.
@proximus-prime: dalej nie odpowiedziałeś na moje pytanie. pytanie jest typu tak lub nie :) w pytaniu czyli któryś z tych projektów w których brałeś udział ma ponad 10 lat i dalej jest porządnie zmodularyzowanym monolitem, który nie utknął w starym stosie technologicznym, tak?
stwierdzenie porządnie zmodularyzowany
oznacza porządnie zmodularyzowany według twojego uznania
. albo może nieco bardziej otwarte pytanie: jak stary jest najstarszy monolit, który jest w zdecydowanej większości zmodularyzowany tak jakbyś chciał i dodatkowo nie utknął w starym stosie technologicznym? (jeśli nie odgadłeś moich intencji to już tłumaczę: nie chodzi mi o to, czy byłeś w stanie zrobić takie moduły jakie chciałeś, tylko jak długo taka modularyzacja przetrwała próbę czasu w komercyjnym zespołowym projekcie.)
Nazwa użytkownika mówi wszystko