Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Microservice - Jak to ugryźć
Forum PHP.pl > Forum > PHP > Object-oriented programming
Pyton_000
Temat nadaje się raczej do Pro wink.gif

Do rzeczy. Mamy dość pokaźną aplikację która została napisana już wieki temu. Przyszedł czas aby zacząć ją migrować na nowe rozwiązania.
Aplikacja z biznesowego pkt. jest podzielona na modułu np. Wyszukiwarka, Klienci, Kontrakty, Firmy itd.

Ogólnie jest to aplikacja do zarządzania rekrutacjami.

Chcemy to zmigrować i postawić w oparciu o Microservices. Tylko jak to ugryźć.
Nie mam doświadczenia w tej materii więc może będzie ktoś kto udzieli jakichś wskazówek.

Założenia są takie że migrujemy na Laravel 5.1 (nie pytajcie dla czego tongue.gif, hejt i tak nic nie wniesie smile.gif ), PHP 5.6 (lub 7).
Jest to dość złożona struktura, dla tego musimy się "wpiąć" w stary system i robić przekierowanie do nowych elementów tak aby móc powoli wyłączać stare rzeczy.

Może ktoś ma jakieś ciekawe materiały na ten temat, jak to ładnie powinno wyglądać.
Wiem tyle że całość ma się opierać o REST i Events.

Czy każdy moduł stawiać jako w pełni działająca aplikacja na FW czy może jakieś inne rozwiązania.
marcio
W tym momencie robimy to samo z systemem ktory zarzadza dns-ami/server-ami/faktory itp... ogolnie dla firmy cloud hosting stara strona byla napisana w symfony 1.4 podzielona na bundle i to wszystko code base to chyba ponad 200kk lini kodu jak nie wiecej.

Teraz przepisujemy kazdy modul z osobna jako aplikacja standalone RESTful (symfony 2.8) jesli chodzi o backend, do tego front-end angularjs + typescript + requirejs + aplikacja symfony 2 ktora robi za kontener na mikro aplikacje kazdego modulu tzn mamy aplikacje web ktora asynchronicznie wczytuje wybrany front-end z mozliwoscia postawienia kazdej z tych mikro aplikacji jako osobna SPA.

Cytat
Jest to dość złożona struktura, dla tego musimy się "wpiąć" w stary system i robić przekierowanie do nowych elementów tak aby móc powoli wyłączać stare rzeczy.

Rozumiem ze cala struktura DB zostaje taka jaka byla wczesniej? Jesli tak to macie identyczna sytuacje jak my wink.gif

W przeciwnym razie dla kazdej aplikacji standalone zrobcie osobne baze danych i komunikujcie za pomoca rest lub ewentualnie zrobie master server ktory bedzie mial sync-a z pozostalymi DB i bedzie aktualizowac dane na bierzaco np za pomoca AWS/RabbitMQ
Pyton_000
Hehe widać nie jestem sam w bólu wink.gif

Tak BD zostaje. Zostanie zmigrowana AWS na kilka instancji.
U nas nie ma w sumie bardzo dużej ilości userów, ale za to DB puchą w szybkim tempie (1 klient ma ok 100GB danych, a spodziewamy się że w ciąku kilku mc +50%).

Do tego jeden wielki monolit który powoli zaczyna być bardzo uciążliwy jeśli chodzi o support, a o nowych fature nie wspomnę.

Dla tego zastanawiamy się jak to ugryźć żeby nie zrobić sobie kuku. Bo stary system ma tyle rzeczy na start robionych że głowa mała wink.gif
lukaskolista
Cytat
Aplikacja z biznesowego pkt. jest podzielona na modułu np. Wyszukiwarka, Klienci, Kontrakty, Firmy itd.
W tym przypadku bardzo dobrze sprawdzi się SOA (polecam fachową literaturę, wiedza na ten temat jest w niej dobrze usystematyzowana).
Pyton_000
Też to rozważam.

Masz może jakieś sprawdzone lektury na ten temat?
marcio
http://microservices.io https://www.nginx.com/blog/building-microse...an-api-gateway/ wink.gif byc moze juz znasz

Jesli chodzi tez o monolithic front-end i migracje do web components as a microservice

http://technologyconversations.com/2015/08...-microservices/
http://blog.xebia.com/the-monolithic-front...s-architecture/
lukaskolista
Ebook porównujący microservices i SOA: https://www.nginx.com/microservices-soa/# za darmo tylko trzeba podac jakieś tam dane.

SOA jest chyba bardziej sformalizowana od microservices, chociaż microservices tak do końca nie znam.

Co do literatury na temat SOA to aktualnie czytam SOA Patterns autorstwa Arnona-Rotem-Gal-Oz w wersji po polsku, tylko to jest raczej o wzorcach soa niż o samej architekturze, ale można wyczuć temat.

Pytanie:
Czy microservice nie jest tak jakby pod SOA? Pytanie trochę niejasne, dlatego wyjaśniam:
Przy zastosowaniu SOA otrzymujemy wiele usług odpowiadających obszarom biznesu, np. usługa Fakturowanie, która obsługuje całą logikę związaną z fakturami. Taka usługa może mieć rozbudowane API, bo faktury można dodawać, korygować, wystawiać pro-forma itp.

Czy microservices nie pokrywa się w pewnym sensie z SOA i nie jest po prostu na niższej warstwie abstrakcji? Z tego co wyczytałem przez ostatnią godzinę microservice to usługa, która ma bardzo ograniczone API, może nawet ograniczać się do wykonywania pojedynczej czynności.

Usługa w ujęciu SOA to po prostu aplikacja odpowiedzialna za dany obszar biznesowy, funkcjonuje pojęcie instancji usługi, co w praktyce często oznacza postawienie klastra active-active z kilkoma węzłami, gdzie na 1 stoi 1 instancja usługi.

Microservice często są tak małe, że stawia się je nawet po kilka na 1 maszynie, a 1 zespół programistów (5-10) osób utrzymuje kilka takich mikro usług (to akurat wyczytałem, bo doświadczenia w microservice nie mam).

Taka usługa w pojęciu SOA może się składać z mikroserwisów - mam rację, czy coś pokręciłem?
marcio
abstrahujac abstrakcje i tak by mozna bylo w nieskonczonosc soa i microservices to jedno i to samo SOA to koncepcja a microservice to wdrozenie SOA w zycie.
lukaskolista
Nie, microservice to nie wdrożenie w życie. Wdrożenie w życie to implementacja, a microservice może mieć wiele różnych implementacji i to jest tak jak SOA architektura. Architektura ma to do siebie, że nie wie nic o implementacji. Temat jest o teoretyzowaniu, więc teoretyzujmy, bo z podejściem "wszystko jedno i to samo" powstają później takie ulepy, które muszę refaktoryzować.
Pyton_000
Każda dyskusja ma sens o ile jest merytoryczna smile.gif

Czytam uważnie waszą dyskusję. Wiem że z wyborem odpowiedniego sposobu na implementację będzie kłopot o tyle że cały zespół musi się wdrożyć w to. Tak więc jest to poniekąd nauka od 0.

Ew. Czy macie jakieś inne propozycje ciekawych architektur które można by zastosować do obecnego układu serwisu?
Dejmien_85
W skrócie:

1. Zerknij na cała aplikację, zlokalizuj moduły i grupy modułów, które zdają się działać "oddzielnie", bez zbyt dużej wymiany zdań z innymi modułami.
2. Podziel te wszystkie moduły (lub grupy) na osobne aplikacje, które komunikują się przez API, przy czym każdy mikro-serwis musi musi być kompletnie niezależny (w tym posiadać osobną bazę danych).
3. Pamiętaj, że jeden mikro-serwis może składać się z kilku modułów. Gdy jakieś moduły są ze sobą ściśle splątane ryżowym makaronem spaghetti, wtedy lepiej je umieścić na jednym serwisie, niż pozwalać na "bogatą", intensywną komunikację pomiędzy tymi serwisami.

Tak, wiem, łatwo się mówi, no ale to jest czysta esencja mikro-serwisów.

I tak jak piszą koledzy powyżej - mikro-serwisy są jak interfejsy. Interfejs sam przez siebie nic nie mówi, to po prostu abstrakcja, a Ty musisz zająć się implementacją.

Kup sobie jakąś porządną książkę o mikro-serwisach i zbadaj ten temat, inaczej będzie to droga przez ból.
Pyton_000
Dość poważny problem tej aplikacji jest taki że niestety są jakieś powiązania międzymodułowe. Więc trzeba będzie zmienić logikę działania całej aplikacji tak aby moduły były całkowicie niezależne.
Co do baz danych to jest kolejny problem. Aplikacja działa w modelu "Saas" gdzie każdy klient ma oddzielną swoją bazę. I teraz byłaby zabawa. Bo w teorii która podałeś trzeba by było odseparować bazy dla modułów a dodatkowo zreplikować je dla każdego klienta oddzielnie.

Niestety nie wchodzi w grę złączenie tabel wszystkich klientów do bazy modułu bo te bazy są "spore". Oczywiście w planie jest zaaplikowanie Elastic do wyszukiwania.
To jest trudny temat do rozgryzienia. A niestety nie możemy wszystkiego zaorać i stworzyć od nowa całego systemu włącznie z BD.
by_ikar
Założenie mikrosewisów nie jest takie że wszystko działa zupełnie odrębnie i żaden nie wie nic o drugim. To jest tak jak w przypadku aplikacji MVC, gdzie poszczególne kontrolery nie są na sztywno powiązane z widokami czy modelami. Te same modele czy widoki możesz również wykorzystać w innej części swojej aplikacji. A taka baza danych to jest część wspólna tych mikroserwisów, bo w jakiś sposób trzeba uwierzytelniać requesty, a najlepiej byłoby tymi samymi danymi. Skoro w tym momencie jakoś już przydzielasz poszczególne bazy danych użytkownikom, to nie ma problemu aby powstało API dzięki któremu takie rzeczy będziesz mógł robić.

Kilka miesięcy temu w końcu w firmie w której pracuje została podjęta decyzja o przepisaniu aplikacji, właśnie z monolita, gdzie wszystko było w jednym repo, wszystko działało na jednym serwerze, rozbudowywanie było trudne, deployment jeszcze trudniejszy etc, przez co jak przyszedł większy ruch, aplikacji zwyczajnie nie dało się skalować, a po mimo moich (nie tylko) uporczywych niekiedy argumentach decyzja za każdym razem była ustala na termin może kiedyś, ja tylko czekałem na większy ruch który ubije aplikację. Kiedy tak się stało, nagle dział marketingu który twierdził że do czegoś takiego nie dojdzie, ocknął się z ręką w nocniku i aplikacje trzeba było przepisywać na wczoraj. Więc im szybciej małymi kroczkami, tym lepiej, a jak ktoś z działu marketingu twierdzi inaczej, to niech to napisze na papieru i się pod tym podpisze, że jeżeli będą problemy w przyszłości, to za nie wszystkie odpowiada właśnie on. Inaczej z tymi mendami się nie da czasami :/
Pyton_000
U nas nie ma takiego problemu. Jest już ustalone, mamy Green Light na prace, oczywiście małymi krokami bo inne rzeczy też trzeba robić. Dlatego plaunjemy najpierw postawienie Fasady która będzie kierowałaruchem do starej i nowej aplikacji i dalej będziemy przenosić poszczególne moduły do nowej części.
lukaskolista
Poniżej moja propozycja, głównie architektura, o implementacji nie będę się rozpisywał.

Na podstawie wiedzy, doświadczenia oraz 2-godzinnego review na temat microservice proponuję takie rozwiązanie:
1. Wyznaczcie autonomiczne obszary biznesowe. Autonomiczne to nie takie, które nie mają powiązań z innymi, bo to by było bez sensu. Chodzi mi o obszary typu: fakturowanie, płatności, marketing itp. Gdybyś przybliżył szczegóły projektu było by łatwiej.
2. Powyższe obszary bezpośrednio mapują się na architekturę SOA - każdy obszar to odrębna usługa. Dobrze to zrobić tak, że każda usługa jest pod dedykowanym load balancerem, bo usługi mogą pracować na kilku węzłach klastra active-active (są nadmiarowe nogi tak, aby w przypadku awarii jednej z nich usługa dalej mogła obsługiwać większe obciążenie). Oczywiście jeśli obciążenie jest małe, to nie ma sensu, wtedy wystarczy active-passive po 1 węźle aktywnym i pasywnym.

Krótko mówiąc: obszar biznesowy = usługa w ujęciu SOA.

Usługi należy rozdzielić pomiędzy zespoły. Jak Was jest np. 5, to macie trochę problem organizacyjny, ale pewnie dacie radę.

Jak już są usługi, to teraz należy zastanowić się nad ich implementacją. Zakładam, że będzie to PHP (pewnie framework) + jakaś baza. Sugeruję użyć wzorców:
Oddzielone wywołanie
Usługa transakcyjna
Usługa aktywna (na 99% się przyda)
Workflow (jeżeli potrzeby biznesu są dynamiczne, np. często tworzone są nowe oferty w ramach tej samej funkcjonalności, ale są różnie obsługiwane, to biznes będzie bardzo zadowolony z użycia tego wzorca)
Potoki równoległe (też pewnie użyjecie, bardzo fajnie się skalują, można wykorzystać system kolejnowania, np. rabbitMQ czy Gearman - gearman w Symfony ma bardzo fajny pakiet, jeżeli byście symfony używali)

Wzorce typu komponent brzegowy pomijam, bo to nie problem zespołu deweloperów danej usługi (chyba, że będziecie utrzymywać serwery produkcyjne).

Następnie zastanowił bym się nad tym, jak poszczególne usługi zaprojektować. Niektóre pewnie można zrealizować na microservice (usługa w pojęciu SOA to niekoniecznie jeden monolit, to raczej jakiś byt z interfacem komunikacji). Taki interface może przyjmować zapytania i przekazywać je wewnętrzenie gdziekolwiek i robić z nimi cokolwiek.

Nie należy każdej usługi robić na microservice, to już zależy konkretnie od potrzeb.

Na koniec:
SOA != microservice
SOA - ujmuje obszary biznesowe jako usługi, może wykonywać wiele czynności
microservice - ujmuje pojedyncze funkcjonalności jako usługi, wykonuje mało czynności, a najlepiej jedną, w której jest wyspecjalizowana (np. generowanie faktury to jeden mikroserwis, bo z punktu widzenia biznesu to jedna czynność)
Należy jedynie zdefiniować pojęcie czynność na odpowiednim poziomie szczegółowości (wystawienie faktury to czynność, wysłanie emaila też, ale mają różny poziom szczegółowości)
Dejmien_85
Cytat(by_ikar @ 29.01.2016, 15:32:01 ) *
Założenie mikrosewisów nie jest takie że wszystko działa zupełnie odrębnie i żaden nie wie nic o drugim.


A kto powiedział, że żaden nie wie o innych?

Założenie jest takie, że serwis jest osobną jednostką, która sobie sama żyje i jest niezależna. Jeśli masz w aplikacji serwis odpowiedzialny za zapis plików (przypuśćmy, że jest osobny serwis, na który wgrywa się wszystkie pliki, czy to zdjęcia, czy PDF, cokolwiek), i teraz wszędzie tam, gdzie aplikacja wymaga wczytywania/odczytywania plików, to "rozmawia" z tym serwisem.

Jedne serwisy mogą tez komunikować się z innymi, ale jeśli przy operacji X serwis A ciągle gada do serwisu B, wtedy lepiej jest połączyć te dwa serwisy w jeden.

Należy unikać sytuacji, kiedy serwisy zbyt często siebie odpytują, bo to jest tylko niepotrzebny "coupling", który później odbija się przy zmianach - w grę wchodzą podstawowe zasady SOLID. Jeśli jeden serwis "rozmawia" z 10 innymi, wtedy przy zmianie tego serwisu może nagle pierdyknąć Ci te 10 serwisów.

Najlepiej narysować sobie na kartce serwisy i narysować strzałki kto z kim gada. Jeśli większość serwisów gada ze sobą nawzajem, wtedy jest to znak, że stworzyłeś cudowny przykład tego, jak nie robić mikroserwisów. ; )

A teraz wracając do Pythona - idźcie małymi kroczkami, znajdźcie jeden moduł, który jest niezależny i po prostu wyrzućcie go na oddzielny serwer. Tylko zanim go wywalicie na serwer, wtedy warto byłoby przeprowadzić najpierw refactoring kodu, postarać się usunąć wszelki niepotrzebny "coupling" tego modułu z innymi. Na waszym miejscu też postarałbym się ograniczyć liczbę zbędnych wywołań tego modułu (w sensie wywołań w kodzie, tylu moduł->metoda), bo podstawą jest, ze każde obecne wywołanie danego modułu będzie zastąpione callem do API.

Łato się mówi, ale oczywiście robi znacznie trudniej. Mikroserwisy to kawał trudnej roboty, powodzenia mogę jedynie życzyć. I koniecznie weź jakąś lekturę, same artykuły Cię wiele nie nauczą. Polecam tą książkę: http://shop.oreilly.com/product/0636920033158.do (czytałem ją w tamtym roku, bardzo fajna, przedstawia konkretne przypadki i problemy z jakimi się boryka, w tym jak dzielić aplikację na serwisy i jak radzić sobie z bazą, np. z transakcjami pomiędzy serwisami).

Weź się za porządną literaturę, ona Ci pomoże, tam ludzie opisują swoje doświadczenia, tutaj jest za dużo teoretyków. ; P
lukaskolista
Cytat
Weź się za porządną literaturę, ona Ci pomoże, tam ludzie opisują swoje doświadczenia, tutaj jest za dużo teoretyków. ; P
Teoria pomaga zapobiec problemom pojawiającym się w praktyce smile.gif Najpierw myślimy, później robimy, a nie na odwrót.
Pyton_000
@lukaskolista, @Dejmien_85 kawał dobrej wypowiedzi exclamation.gif

Dobra, ogólnie aplikacja to narzędzie do przeprowadzania procesów rekrutacyjnych.

Firma rekutująca ma swoich rekruterów (recruiters) którzy to dla swoich klineót (clients) zbiera kandydatów (candidates).
Klienci tworzą miejsca pracy (vacancies) i na koniec po procesie rekrutacji przypisują vacancies do candidates (placement).

Do tego dochodzą mejle wszelakie, notatki client/candidate/vacancy i w piz....u innych rzeczy.

System wyszukiwania wszystkich powyższych włączając w to muuultum kryteriów. Automatching, statusy, informacje o kandydatach (tego jest od groma).

W skrtócie cholernie skomplikowana logika biznesowa smile.gif
Komunikacja czasami też jest rózna np. wchodząc w klienta widzimy też jego vacancies, konta bilingowe, kandydatów itd itd. Więc jak widać komuniacja tutaj będzie dość często w formie gwiazdy... czyli 1 moduł musi mieć informacje od kilku innych.

Dodatkowo jeszcze CV ale to już mało istotny element bo ten na pewno będzie wydzielone.
Raporty tak samo.

To taki mocno ogólny zarys systemu.
lukaskolista
Na jakim systemie bazodanowym to macie postawione? Zakładam, że nie jest to MySQL.
Pyton_000
Tak, Mysql, serwis działa od 2006 roku wink.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.