19 września w Moskwie pierwsze tematyczne spotkanie HUG (Highload++ User Group), które było poświęcone mikroserwisom. Zanotowaliśmy wykład „Eksploatacja mikroserwisów: rozmiar ma znaczenie, nawet jeśli masz Kubernetes”, w którym podzieliliśmy się bogatym doświadczeniem firmy „Flant” w zakresie eksploatacji projektów z architekturą mikroserwisową. Przede wszystkim będzie on przydatny dla wszystkich programistów zastanawiających się nad zastosowaniem tego podejścia w swoim obecnym lub przyszłym projekcie.

Prezentujemy (50 minut, znacznie bardziej informacyjne niż artykuł), a także główną treść w formie tekstowej.
NB: Wideo i prezentacja są również dostępne na końcu tej publikacji.
Wprowadzenie
Zazwyczaj dobra historia ma wprowadzenie, główny wątek i zakończenie. Ten wykład bardziej przypomina wprowadzenie, co więcej, tragiczne. Ważne jest również, aby zauważyć, że prezentuje on perspektywę mikroserwisów z punktu widzenia eksploatację.
Zacznę od takiego wykresu, którego autorem (w 2015 roku) Martin Fowler:

Na nim widać, jak w przypadku monolitycznej aplikacji, która osiągnęła określony rozmiar, zaczyna spadać produktywność pracy. Mikroserwisy różnią się tym, że początkowa produktywność z nimi jest niższa, jednak w miarę wzrostu złożoności degradacja efektywności nie jest tak zauważalna.
Uzupełnię ten wykres dla przypadku użycia Kubernetes:

Dlaczego aplikacja z mikroserwisami się poprawiła? Ponieważ taka architektura stawia poważne wymagania, które są świetnie spełniane przez możliwości Kubernetes. Z drugiej strony, część tej funkcjonalności będzie przydatna również dla monolitu, szczególnie z tego powodu, że typowy dzisiaj monolit to nie do końca monolit (szczegóły zostaną omówione później w wykładzie).
Jak widać, ostateczny wykres (gdy zarówno aplikacje monolityczne, jak i mikroserwisowe znajdują się w infrastrukturze Kubernetes) niewiele różni się od początkowego. Następnie będziemy mówić o aplikacjach eksploatowanych z użyciem Kubernetes.
Pożyteczność i szkodliwość mikroserwisów
I tu główna myśl:

Czym jest normalna architektura mikroserwisowa? Powinna przynosić ci rzeczywiste korzyści, zwiększając efektywność pracy. Jeśli wrócimy do wykresu, oto ona:

Jeśli nazwiemy ją przydatna, to po drugiej stronie wykresu znajdzie się szkodliwa mikroserwisowość (przeszkadza w pracy):

Wracając do "głównej myśli": czy w ogóle warto zaufać mojemu doświadczeniu? Od początku tego roku obejrzałem 85 projektów. Nie wszystkie z nich były mikroserwisowe (taka architektura miała około jednej trzeciej do połowy z nich), ale to wciąż duża liczba. Nam (firmie „Flant”) jako dostawcom zewnętrznym udaje się dostrzegać różnorodność aplikacji, rozwijanych zarówno w małych firmach (z 5 programistami), jak i w dużych (~500 programistów). Dodatkowym plusem jest to, że widzimy, jak te aplikacje żyją i rozwijają się przez wiele lat.
Po co mikroserwisy?
Na pytanie o użyteczność mikroserwisów jest od wspomnianego już Martina Fowlersa:
- wyraźne granice modularności;
- niezależne wdrażanie;
- wolność wyboru technologii.
Dużo rozmawiałem z architektami i programistami oprogramowania i pytałem, dlaczego potrzebują mikroserwisów. Sporządziłem swoją listę ich oczekiwań. Oto, co wyszło:

Jeśli opisać "w odczuciu" niektóre z punktów, to:
- wyraźne granice modułów: oto mamy straszny monolit, a teraz wszystko będzie starannie uporządkowane w repozytoriach Git, w których wszystko jest "na półkach", nie pomieszane ciepłe z miękkim;
- niezależność wdrażania: będziemy mogli wdrażać usługi niezależnie, aby rozwój przebiegał szybciej (równolegle publikować nowe funkcje);
- niezależność w rozwijaniu: możemy oddać ten mikroserwis temu zespołowi/programiście, a tamten — innemu, dzięki czemu będziemy mogli szybciej rozwijać;
- bwiększąwiększa niezawodność: jeśli wystąpi częściowa degradacja (jedna z 20 mikroserwisów upadnie), to przestanie działać tylko jeden przycisk, a cały system nadal będzie funkcjonować.
Typowa (szkodliwa) architektura mikroserwisów
Aby wyjaśnić, dlaczego w rzeczywistości wszystko nie jest takie, jak oczekujemy, przedstawię zbiorowy obraz architektury mikroserwisowej, oparty na doświadczeniach z wielu różnych projektów.
Przykładem będzie abstrakcyjny sklep internetowy, który planuje konkurować z Amazonem lub przynajmniej OZON. Jego architektura mikroserwisowa wygląda następująco:

Z wielu powodów te mikroserwisy są napisane na różnych platformach:

Ponieważ każdy mikroserwis powinien być autonomiczny, wiele z nich potrzebuje własnej bazy danych i cache'a. Ostateczna architektura przedstawia się następująco:

Jakie są jej konsekwencje?
Fowler ma w tej kwestii – o 'zapłacie' za korzystanie z mikrousług:

Zobaczymy, czy nasze oczekiwania się spełniły.
Wyraźne granice modułów...
Ale ile mikrousług musimy naprawdę poprawić, aby wprowadzić zmianę? Czy w ogóle możemy zrozumieć, jak to wszystko działa, bez rozproszonego narzędzia do śledzenia (przecież każde zapytanie jest obsługiwane przez połowę mikrousług)?
Istnieje wzorzec '', a tutaj mamy całkowicie rozproszoną kulkę brudu. Oto przykładowa ilustracja tego, jak przebiegają zapytania:

Niezależność wdrożenia...
Pod względem technicznym została osiągnięta: możemy zaktualizować każdą mikrousługę oddzielnie. Ale w praktyce trzeba pamiętać, że zawsze wdrażanych jest wiele mikrousług, musimy również uwzględnić kolejność ich wdrożenia. Powinniśmy w ogóle testować w oddzielnym otoczeniu, czy wdrażamy wersję w odpowiedniej kolejności.
Wolność wyboru technologii...
Jest. Tylko trzeba pamiętać, że często wolność graniczy z chaosem. Ważne jest, aby nie wybierać technologii tylko po to, aby 'pobawić się' nimi.
Niezależność w rozwoju...
Jak stworzyć testowe otoczenie dla całej aplikacji (z tak wielu komponentów)? A przecież trzeba to również utrzymywać w aktualnym stanie. To wszystko prowadzi do tego, że rzeczywista liczba testowych otoczeń, które możemy utrzymać, okazuje się minimalna.
A jak wdrożyć to wszystko lokalnie? Okazuje się, że często programista wykonuje swoją pracę niezależnie, ale "na ślepo", ponieważ jest zmuszony czekać, aż otoczenie do testowania się zwolni.
Oddzielne skalowanie...
Tak, ale jest to ograniczone w zakresie używanych baz danych. W podanym przykładzie architektura nie sprawia problemów z Cassandra, ale będą one z MySQL i PostgreSQL.
Bwiększąardzo większa niezawodność...
Nie tylko to, że w rzeczywistości awaria jednej mikrousługi często łamie poprawne działanie całego systemu, to pojawia się jeszcze nowy problem: uczynić każdą mikrousługę odporną na awarie jest bardzo trudne. Ponieważ w mikrousługach używane są różne technologie (memcache, Redis itd.), dla każdej z nich trzeba wszystko przemyśleć i wdrożyć, co, oczywiście, jest możliwe, ale wymaga ogromnych zasobów.
Mierzenie obciążenia…
Z tym naprawdę wszystko w porządku.
„Lekkość” mikroserwisów…
Mieliśmy nie tylko ogromne narzuty sieciowe (wzrastające zapytania do DNS itd.), ale także z powodu licznych zapytań zaczęliśmy replikować dane (przechowywać pamięci podręczne), co doprowadziło do znacznej ilości przechowywania.
I oto jak wygląda zgodność z naszymi oczekiwaniami:

Ale to jeszcze nie wszystko!
Ponieważ:
- Prawdopodobnie będziemy potrzebować szyny komunikacyjnej.
- Jak zrobić spójny backup w odpowiednim czasie? Jedyną realną opcją jest wyłączenie ruchu na ten czas. Ale jak to zrobić na produkcji?
- Jeśli mówimy o wsparciu wielu regionów, zorganizowanie odporności w każdym z nich to bardzo pracochłonne zadanie.
- Pojawia się problem wprowadzania zmian w sposób centralny. Na przykład, jeśli musimy zaktualizować wersję PHP, będziemy musieli dokonać commitu w każdym repozytorium (a jest ich dziesiątki).
- Wzrost operacyjnej złożoności zdaje się być wykładniczy.
Co z tym wszystkim zrobić?
Zacznijcie od monolitycznej aplikacji. Doświadczenie Fowlera dotyczy tego, że prawie wszystkie udane aplikacje mikroserwisowe zaczynały się od monolitu, który stał się zbyt duży, a następnie został podzielony. Równocześnie prawie wszystkie systemy zbudowane jako mikroserwisowe od samego początku, prędzej czy później napotykały poważne problemy.
Jeszcze jedna cenna myśl — aby projekt z architekturą mikroserwisową odniósł sukces, musisz bardzo dobrze znać zarówno dziedzinę przedmiotu, jak i to, jak robić mikroserwisy. A najlepszym sposobem na poznanie dziedziny przedmiotu jest stworzenie monolitu.
Ale co zrobić, jeśli już znaleźliśmy się w takiej sytuacji?
Pierwszym krokiem do rozwiązania jakiegokolwiek problemu jest zaakceptowanie go i zrozumienie, że to problem, że nie chcemy już cierpieć.
Jeśli w przypadku rozrośniętego monolitu (kiedy brak jest możliwości dokupienia zasobów) przecinamy go, to w tym przypadku mamy odwrotną sytuację: gdy nadmierna mikroserwisowość już nie pomaga, a przeszkadza — przecinajcie to, co zbędne i łączcie!
Na przykład, dla rozważanego powyżej zbiorczego obrazu…
Pozbądźcie się najbardziej wątpliwych mikroserwisów:

Połączcie wszystkie mikroserwisy odpowiedzialne za generację frontendu:

… w jednej mikroserwisie, napisanym w jednym (nowoczesnym i dobrym, jak uważacie) języku/frameworku:

Będzie miał jedną ORM (jedną bazę danych) i na początku kilka aplikacji:

… w ogóle można przenieść znacznie więcej, osiągając taki efekt:

W Kubernetes uruchamiamy to wszystko jako oddzielne instancje, a to oznacza, że wciąż możemy mierzyć obciążenie i skalować je oddzielnie.
Podsumowując,
Spójrz na sytuację z szerszej perspektywy. Bardzo często wszystkie te problemy z mikroserwisami wynikają z tego, że ktoś wziął swoje zadanie, ale chciał „pobawić się w mikroserwisy”.
W słowie „mikroserwisy” część „mikro” jest zbędna.. Są „mikro” tylko dlatego, że są mniejsze od ogromnego monolitu. Ale nie myśl o nich jako o czymś małym.
A dla finalnej myśli wróćmy do pierwotnego wykresu:

Przypis do niego (w prawym górnym rogu) sprowadza się do tego, że umiejętności zespołu, który realizuje Twój projekt, zawsze mają kluczowe znaczenie — właśnie one odegrają decydującą rolę w Twoim wyborze między mikroserwisami a monolitem. Jeśli zespół nie ma wystarczających umiejętności, ale zaczyna robić mikroserwisy, historia z pewnością zakończy się katastrofą.
Wideo i slajdy
Wideo z wystąpienia (~50 minut; niestety, nie oddaje ono licznych emocji odwiedzających, co w dużej mierze kształtowało nastrój prezentacji, ale takie jest życie):

Prezentacja wystąpienia:
P.S.
Inne wystąpienia w naszym blogu:
- «» (Dmitrij Stoljarow; 28 maja 2018 na RootConf);
- «» (Dmitrij Stoljarow; 7 listopada 2017 na HighLoad++);
- «» (Dmitrij Stoljarow; 6 czerwca 2017 na RootConf);
- «» (Dmitrij Stoljarow; 8 listopada 2016 na HighLoad++);
- «» (Dmitrij Stoljarow; 31 maja 2016 na RootConf).
Prawdopodobnie zainteresują Cię również następujące publikacje:
- «»;
- «»;
- «».
Źródło: habr.com
