Jak poprawnie zaprojektować mikroserwisy?

0

Cześć. To będzie mój pierwszy projekt z wykorzystaniem architektury mikroserwisów, także proszę Was o wyrozumiałość. Poczytałem trochę na ten temat, także o podejściu DDD ale mam nadal kilka pytań w zakresie praktycznego zaprojektowania aplikacji wykorzystującej mikroserwisy w ASP Net Core. Chodzi o dobre praktyki bazując na doświadczeniu osób obeznanych w tym temacie. Mój projekt nie będzie jakiś duży, powiedzmy na start 6-7 serwisów ale z możliwością dołożenia nowych. Mimo wielkości projektu nie chcę tworzyć monolitu tylko wejść w mikroserwisy. Moje pytania są zadawane w kontekście projektu ASP Net Core:

  1. czy powinienem stworzyć kilka serwisów pod jedną solucją (solution) czy może nowe solution dla każdego serwisu? Nie mówimy tu też o GitHubie, chodzi mi o Visual Studio
  2. jeśli kilka serwisów pod jedną solucją to jak wygląda kwestia deployowania? Czytałęm o dobrej praktyce, wg której każdy serwis to oddzielna aplikacja niezależna od innych i deployowana oddzielnie.
  3. czy API Gateway powinno działać jako oddzielna aplikacja czy może jednak być podpięte pod jakiś istniejący solution i reszta solutions by też z niego korzystała?
  4. czy mikroserwisy , które utworzę powinny być konteneryzowane czy może nie jest to konieczne?
  5. czy mikroserwisy można zdeployować na produkcji bez kontenerów?
  6. cała aplikacja będzie de facto korzystała z jednej bazy danych na jednym serwerze - mamy tam wszystkie potrzebne dane do działania apki. Czytałem jednak, że wg dobrych praktyk każdy serwis powinien mieć swoją bazę danych. Pytanie - czy mogę, przeciwnie do dobrych praktyk, używać jednej bazy danych dla wszystkich serwisów (każdy z serwisów będzie ciągnął dane z innych tabel, nie będą współdzieliły)?
  7. niejako nawiązanie do pkt.7 - czy ma sens stworzenie dedykowanego serwisu, który będzie pobierał dane z bazy potrzebne moim wszystkim serwisom? Wtedy każdy serwis pobierałby dane używając API z jednego miejsca - tego właśnie serwisu z danymi. Czy może lepiej, żeby każdy serwis miał oddzielne połączenie z bazą danych i niezależnie funkcjonował, w oderwaniu od mikroserwisu z danymi?

Dziękuje z góry za odpowiedzi. Próbuję sam ogarnąć te mikroserwisy, nikt nie robił w firmie tego przede mną więc nie mam wypracowanego wzorca. Mam nadzieję, że podpowiecie mi jak zrobić to z praktycznego punktu widzenia.

2

Hmm myślę, ze zanim już podejmiesz decyzję czy isc w architekturę mikroserwisowa to trzeba sie poważnie zastanowić, bo jeśli domena i problem mało złożony to mikroserwis to przerost formy nad treścią i dokładanie niepotrzebnego skomplikowania.

Z tego co znam to każdy mikroserwis = osobna solucja, gateway też osobna solucja. Cała aplikacja będzie korzystała z jednej bazy danych - WTF? Przecież o to chodzi w mikroserwisach żeby podzielić a nie łączyć.

Czy można je deployowac bez kontenerów? Tak.

Ostatnie pytanie żeby tworzyć serwis który będzie zasysał dane - imo wbrew założeniom architektury mikroserwisowej.

Generalnie to mogę książkę o polecić od Microsoftu na ten temat jak i przykładowa implementację tematu here: https://learn.microsoft.com/en-us/dotnet/architecture/microservices/

Jestem ciekaw, co inni powiedzą, bo to żywy temat jest 😊

2

Lepiej zastanów się w jaki sposób będziesz osiągał spójność danych pomiędzy serwisami, i czy będą się ze sobą komunikować synchronicznie czy asynchronicznie. Skoro chcesz użyć jednego wspólnego źródła danych, najwyraźniej nie przewidujesz problemów wydajnościowych źródła danych. Źródło danych zwykle skaluje się najtrudniej, stąd właśnie, autonomiczność serwisów i posiadanie przez nich własnego źródła jest tak ważne i stanowi jedną z najważniejszych zalet tej architektury

Kontenery to jest standard, im więcej różnych (egzotycznych) serwisów do zdeployowania tym bardziej je się docenia.

PS: Jeśli odpowiedź na pierwsze pytanie to transakcje i synchronicznie, to będzie to miało niewiele wspólnego z mikroserwisami.

2
  1. Jeżeli robisz to dla zabawy, możesz wykorzystać monorepo dla wszystkich serwisów.
  2. Właśnie po to stostuje się architekturę mikroserwisową, żeby mięc niezależne wdrożenia :)
  3. Oddzielny serwis
  4. Powinny
  5. Można, ale po co komplikować sobie życie.
  6. Możesz użyć jednej, każdy serwis ma własną niezależną scheme.
  7. A jak myślisz co się stanie jak ten serwis padnie ? Dalej aplikacja będzie działać ?

Ogólnie to widać, że dopiero zaczynasz, więc polecam zacząć od poczytania po co stosuje się mikroserwisy, jaka jest ich największa zaleta ? Nie jest to skalowalność.
Nie martw się wiekszość ludzi i tak kończy z rozproszonym monolitem zamiast mikro, bo na konferencji usłyszeli. Ja bym zaczął od modularnego monolitu, bo to taki krok nr1. przed mikro, a pożniej decydujesz, który moduł chcesz wyciągnać jako osobny serwis.

4
muskagap napisał(a):

Cześć. To będzie mój pierwszy projekt z wykorzystaniem architektury mikroserwisów,

A robisz to z jakiegoś konkretnego powodu, czy "po prostu chcesz sobie ich użyć"? Bo jeśli "tak po prostu", to na 99% są niepotrzebne, i nie zrobisz microserwisów tylko niepotrzebne trzy apki.

Bo ogólnie, lista kroków:

  1. Aplikacja która ma jeden moduł.
  2. Dochodzą do aplikacji więcej zależności, i jeśli ktoś jest rozgarnięty, to nie napisze ich w tym jednym module, tylko rozdzieli go na niezależne moduły
  3. Jeśli dochodzi jeszcze więcej zależności, może zajść potrzeba jeszcze większej separacji między modułami

(i tu może warto dodać, że takie poprawne rozdzielenie na moduły ogarnia 99.9999999999% wszystykich potrzeb odseparowania na rynku; a ludzie z tego robią mikroserwisy właściwie tylko dlatego że są modne).

  1. Jeśli nadal faktycznie potrzebujesz większego odseparowania modułów od siebie, to wtedy można takie moduły wynieść do osobnej aplikacji, i komunikować je po sieci (np po HTTP); co jest oczywiście dużo trudniejsze niż np wystawić interfejs z jednego modułu. Noi takie postawienie wielu aplikacji testuje się też dużo ciężej, i ciężej znaleźć zmiany które psują inne serwisy. Dodatkowo zabawne jest to że ludzie którzy budują takie mikroserwisy uwielbiają mówią że one są "niezależne od siebie", ale niestety kontrakty między nimi są często mapowane 1:1, więc zmiana jednego psuje drugi, i tyle z tej niezależności.

Także moja rada: Zajmij się czymś pożytecznym.

PS: Jak faktycznie projektujesz mikroserwisy to wybór ich technologii nie ma znaczenia, mogą być napisane jeden w pythonie drugi w javie.

1

Polecam zapoznać się z koncepcją modularnego monolitu zrobionego w .Net link
Bo z tego co piszesz to jest mały projekt pisany tylko przez ciebie a jak go podzielisz na x-serwisów, kilka solucji to sam się w tym zgubisz po czasie i finalnie zamiast tworzyć aplikację będziesz walczyć z architekturą. A z dobrze zrobionego monolitu przejść na microserwisy to już nie jest problem.

2

Nigdy, ale to nigdy wiele mikroserwisow nie powinno korzystac z tej samej bazy danych. Jezeli jest to projekt 4fun to smialo rob sobie co tam chcesz, ale jesli to ma byc cos wiecej to zgadzam sie z wyzej wymienionymi opiniami - ogarnij czym jest modularny monolit.

Nie majac wiedzy teoretycznej ani doswiadczenia to co sam zrobisz najprawdopodobniej bedzie rozproszonych monolitem, gdzie serwisy beda sie cechowac wysokim sprzezeniem i niska spojnoscia.

btw Mikroserwisy nigdy nie powinny byc domyslnym wyborem architektonicznym, powinno sie najpierw zastanowic dlaczego, po co, jakie sa korzysci itp. Wraz z mikroserwisami najczesciej mocno wzrasta ilosc kodu, potrzebnych narzedzi itd.

edit: Jesli masz w firmie dostep do o'reilly to przeczytaj sobie ksiazke "Building Microservices".

2

Co do konteneryzacji: jak/gdzie masz zamiar deployowac? Na k8s docker jest praktycznie domyslnym podejsciem.

Mysl tez pod katem utrzymania:

  • najlepiej stateless jesli to tylko mozliwe, bo wtedy jak cos padnie robisz delete serwera, stawia sie nowy i tyle.
  • latwe skalowanie (w gore i w dol), czyli po prostu stawiasz serwis i dziala wystarczy ze loadbalancer zrobi swoja robote.
    • co do bazy, IMHO baza jako osobny byt, chyba ze jakas lokalna do przechowywania konfiguracji. Na AWS masz teraz chocby bardzo popularna Aurore.
      • kazda technologie ktora tam wpakujesz trzeba pozniej utrzymywac, aktualizowac pod katam CVE itp. Pomysl tez o tym.
      • Pamietaj o migracji :P
0

Dziękuję wszystkim za odpowiedzi. Trochę rozjaśniliście mi temat. Zasadniczo moja aplikacja może nie będzie duża w kontekście liczby korzystających z niej userów (kilkudziesiąt osób) natomiast będzie względnie skomplikowana jeśli chodzi o funkcjonalności, moduły, analizy, obliczenia itd. Apkę będe w całości pisał sam, nie mam żadnego teamu. Faktycznie, chciałem wprowadzić trochę świeżości do podejścia w tworzeniu aplikacji w firmie ale widzę, że jednak mikroserwisy nie mają tu większego sensu.

Napisałem już część front-endową (Vue.js), teraz tworzę backend w Net Core. Nie robię apki MVC, ciałem rozdzielić front i back na 2 apki. Front napisałem jako oddzielną apkę korzystając z Visual Studio Code. Backend czyli API piszę tez jako zupełnie oddzielną apkę w C#. Te 2 oddzielne apki bedę komunikował poprzez API. I tak naprawdę tutaj był mój punkt wyjścia - nie chciałem pakować całej logiki do jednej, backendowej apki, żeby kontrolery mi nie napuchły. Tak jak wspomniałem w apce będzie dużo funkcjonaloności więc pomyślałem, że porobię oddzielne serwisy dla określonych obszarów biznesowych (z oddzielną logiką). Mając takie oddzielne 'tematyczne' serwisy będzie to bardziej przejrzyste.

Wspomnieliście jednak o modularnym monolicie co wydaje się swego rodzaju kompromisem w moim przypadku. Rozumiem, że, mówiąc z grubsza, pod Solution tworzę kilka oddzielnych projektów, które odpowiadają za konkretną logikę biznesową. Wtedy uruchamiane są w jednym procesie i deployowane w tym samym czasie. Warstwa fron-endowa może natomiast być napisana jako zupełnie oddzielna apka i obie częście (front i back) komunikuję wtedy poprzez jakieś API. Tak to bym widział. Jeśli macie jakieś uwagi bądź dobre rady w tym zakresie proszę dajcie znać.

2
muskagap napisał(a):

Apkę będe w całości pisał sam, nie mam żadnego teamu.

A sens mikroserwisów zaczyna się tam, gdzie system jest zbyt duży, aby dał się sensownie rozwijać jako całość przez wiele zespołów. Poszczególne mikroserwisy są tworzone i utrzymywane przez oddzielne zespoły.
Skoro będziesz pracował sam, to to nie jest skomplikowany system, więc drugim powodem użycia mikroserwisów mogłaby być chęć niezależnego skalowania wynikająca z różnego obciążenia poszczególnych elementów systemu. Bardzo wątpliwe, aby przy kilkudziesięciu użytkownikach, było to uzasadnione.

Te 2 oddzielne apki bedę komunikował poprzez API. I tak naprawdę tutaj był mój punkt wyjścia - nie chciałem pakować całej logiki do jednej, backendowej apki, żeby kontrolery mi nie napuchły. Tak jak wspomniałem w apce będzie dużo funkcjonaloności więc pomyślałem, że porobię oddzielne serwisy dla określonych obszarów biznesowych (z oddzielną logiką). Mając takie oddzielne 'tematyczne' serwisy będzie to bardziej przejrzyste.

No to może jednak zastosuj MVC (albo jakąś inną architekturą), wydziel logikę aplikacyjną i biznesową z kontrolerów, zaimplementuj sensowną warstwę domeny. Bo jak na razie, to najwyraźniej masz spaghetti, a tego mikroserwisy nie naprawią.

2

Zasadniczo moja aplikacja może nie będzie duża w kontekście liczby korzystających z niej userów (kilkudziesiąt osób) natomiast będzie względnie skomplikowana jeśli chodzi o funkcjonalności, moduły, analizy, obliczenia itd. Apkę będe w całości pisał sam, nie mam żadnego teamu

Zamiast próbować się wpasować w jakiś wzorzec, to lepiej miej dwie rzeczy na uwadze - te, które sam napisałeś:

  • apkę piszesz sam - więc pomyśl, co tobie będzie wygodnie, jak chcesz ją pisać, jak rozwijać. Bo w tej sytuacji wrzucanie wszystkiego w mikroserwisy, które na dodatek są dla ciebie nowe, brzmi jak sabotaż własnej produktywności. Przecież to ty będziesz musiał utrzymywać później te repa, solucje, pisać konfigi itp. (Jakbyś miał w tym doświadczenie to spoko, ale wchodzenie w to tak to trochę bez sensu)

  • apke piszesz dla kilkudziesięciu userów, więc pomyśl o ich potrzebach. Coś tam pytałeś o deployu:

    jeśli kilka serwisów pod jedną solucją to jak wygląda kwestia deployowania? Czytałęm o dobrej praktyce, wg której każdy serwis to oddzielna aplikacja niezależna od innych i deployowana oddzielnie.

    Czy masz praktyczną potrzebę oddzielania deployów? Może tak (np. żeby przetestować jakieś funkcjonalności na wąskiej grupie userów?). Ale mam wrażenie, że wychodzisz od d**y strony czyli od wzorca projektowego (=rozwiązania), zamiast wyjść od problemów, które pragniesz rozwiązać. I w efekcie robi się cargo cult

czy mikroserwisy , które utworzę powinny być konteneryzowane czy może nie jest to konieczne?
czy mikroserwisy można zdeployować na produkcji bez kontenerów?

Mogę się mylić, ale brzmi trochę jakbyś nie znał kontenerów i bal się ich nauczyć.

3

Ja tylko dorzucę kilka groszy. Warto się zastanowić, zanim wejdzie się w architekturę mikro serwisów, czy w zasadzie masz realną przestrzeń (czyt. infrastrukturę) do rozwiązywania problemów w tym wzorcu. Skoro problem zostanie za modelowany na X mniejszych problemów, a każdy z tych X generuje zdarzenia, to byłoby idealnie móc monitorować stan wykonywanych operacji, e.g. distributed tracing, errors aggregation, errors propagration.

0

Tak jak napisałem - zaczynałem od MVC, chcę pójśc o krok dalej. Rozumiem, że mikroserwisy nie są najlepszym rozwiązaniem w moim przypadku. Tak, to już wiem. Co do rozpoznania problemów biznesowych, podziału na logiczne części to mam to opracowane - chodzi mi teraz właśnie o wzorzec. Sugerowaliście modularny monolit, kóry w moim przypadku zdecydowanie bardziej zdałby egzamin i z dużym prawdopodobieństwem pójdę w to rozwiązanie. Mam już napisaną wstepną wersję front-endu. Natomiast nie piszę warstwy frontowej w C# (tak jakbym to robił przy zwykłym MVC), piszę oddzielną aplikację frontendową w Vue.js. Będą ją chciał następnie skomunikować z docelowym modularnym monolitem. Nie robiłęm tego wcześniej więc zastanawiam się tylko czy nie będzie to problematyczne w jakimś stopniu - mam na myśli skomunikowanie fronta z backiem i deployowania ich na serwerze jako 2 oddzielne apki (na IIS).

0

mam na myśli skomunikowanie fronta z backiem i deployowania ich na serwerze jako 2 oddzielne apki

Front i back mogą być nawet na oddzielnych serwerach. Front możesz sobie serwować nawet jako strony statyczne, Backend już będzie wymagać tego, żeby serwer obsługiwał dany język programowania na backendzie.

deployowania

Jak to dokładnie deployujesz teraz? Masz jakąś automatyzację tego deploya?

0

Aplikację publikuję a następnie pliki wrzucam ręcznie na serwer, nie ma automatyzacji. Z czasem chciałem dołożyć do aplikacji skrypty w R i Pythonie bo mam zamiar użyć ich do pewnych analiz. Ale to już temat na inny post,jak zintegrować takie skrypty z apką backendową i zdeployować na serwerze. Tak czy inaczej zacznę od integracji fronta z backiem i wrzuceniem na serwer, żeby sprawdzić jak to działa.

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