Читать книгу Mikroserwisy w akcji - Группа авторов - Страница 14
Część 1
Stan rzeczy
1. Projektowanie i uruchamianie mikroserwisów
1.2. Co w mikroserwisach jest wyzwaniem?
ОглавлениеZagłębmy się nieco w temat i zbadajmy koszty oraz złożoność projektowania i uruchamiania mikroserwisów. Mikroserwisy nie są jedyną architekturą, która obiecała nirwanę dzięki dekompozycji i rozproszeniu, ale ostatnie próby, takie jak SOA4, są powszechnie uważane za nieskuteczne. Żadna technika nie jest magicznym narzędziem. Na przykład, jak już wspomnieliśmy, mikroserwisy drastycznie zwiększają liczbę odrębnych elementów w systemie. Rozdzielając funkcjonalności i odpowiedzialność za dane na wiele autonomicznych usług, jest również rozdzielana odpowiedzialność za stabilność i właściwedziałanie aplikacji.
Podczas projektowania i uruchamiania aplikacji mikroserwisowych napotkamy wiele wyzwań:
■ określanie zakresu i identyfikowanie mikroserwisów wymaga znacznej wiedzy na temat domeny ich zastosowania;
■ właściwe granice i kontrakty między usługami są trudne do zidentyfikowania i, po ich ustaleniu, ich zmiany mogą być czasochłonne;
■ mikroserwisy są systemami rozproszonymi i dlatego wymagają wielu założeń dotyczących stanu, spójności i niezawodności sieci;
■ przez rozproszenie komponentów systemu w sieci i zwiększenie heterogeniczności technicznej mikroserwisy wprowadzają nowe typy awarii;
■ trudniej jest zrozumieć i zweryfikować, co powinno się zdarzyć podczas normalnej pracy.
1.2.1. Wyzwania związane z projektowaniem
W jaki sposób te wyzwania wpływają na fazę projektowania i uruchamiania mikroserwisów? Wcześniej wprowadziliśmy pięć podstawowych zasad tworzenia mikroserwisów. Pierwszą z nich była autonomia. Aby nasze usługi były autonomiczne, musimy je tak zaprojektować, aby razem były luźno powiązane i każda zawierała wysoce spójne elementy funkcjonalności. Jest to proces ewolucyjny. Zakres naszych usług może się zmieniać w miarę upływu czasu, a my będziemy często się decydować na wyodrębnienie nowej funkcjonalności z usług, a nawet wycofanie już istniejących.
Dokonywanie tych wyborów jest wyzwaniem, szczególnie istotnym na początku opracowywania aplikacji! Głównym źródłem luźnych powiązań są granice między usługami; zły wybór doprowadzi do usług, które są trudne do zmiany i, ogólnie, mniej plastyczne i elastyczne do zastosowania.
OKREŚLANIE ZAKRESU MIKROSERWISÓW WYMAGA WIEDZY NA TEMAT DOMENY ICH ZASTOSOWANIA
Każdy mikroserwis jest odpowiedzialny za pojedynczą zdolność. Identyfikacja tych zdolności wymaga znajomości domeny biznesowej aplikacji. W początkowej fazie życia aplikacji nasza wiedza o domenie może być w najlepszym razie niekompletna lub, w najgorszym, niepoprawna.
Nieodpowiednie zrozumienie domeny problemu może skutkować złymi wyborami projektowymi. W aplikacji mikroserwisowej zwiększona sztywność granicy usługi w porównaniu z modułem w aplikacji monolitycznej oznacza, że koszt złych decyzji dotyczących zakresu może być wyższy:
■ być może trzeba będzie refaktoryzować wiele różnych baz kodów;
■ konieczna może być migracja danych z bazy danych jednej usługi do drugiej;
■ możliwe, że nie zostaną zidentyfikowane niejawne zależności między usługami, co może prowadzić do błędów lub niezgodności podczas wdrażania.
Czynności te zilustrowano na rysunku 1.5.
Jednak podejmowanie decyzji projektowych, przy niewystarczającej wiedzy o danej dziedzinie, nie jest rzadkością w przypadku mikroserwisów! Różne są skutki tych decyzji.
UWAGA W rozdziałach 2 i 4 za pomocą przykładowej aplikacji omówimy dobre praktyki dotyczące identyfikowania i określania zakresów usług.
ZARZĄDZANIE KONTRAKTAMI MIĘDZY USŁUGAMI
Każdy mikroserwis powinien być niezależny od sposobu implementacji innych usług. Pozwala to na techniczną heterogeniczność i autonomię. Aby to działało, każdy mikroserwis powinien wystawiać kontrakt – analogicznie do interfejsu w projektowaniu obiektowym – określający komunikaty, które spodziewa się otrzymywać i na które będzie udzielać odpowiedzi. Dobry kontrakt powinien być:
■ kompletny – definiuje pełny zakres interakcji;
■ zwięzły – nie wymaga więcej informacji niż jest to konieczne, tak, aby konsumenci mogli konstruować komunikaty w rozsądnych granicach;
■ przewidywalny – dokładnie odzwierciedla rzeczywiste zachowanie implementacji.
Rysunek 1.5. Nieprawidłowe decyzje dotyczące zakresu usług mogą wymagać złożonej i kosztownej refaktoryzacji w obrębie granic usług
Każdy kto projektował API, wie, jak trudno osiągnąć takie cechy. Kontrakty są spoiwem między usługami. Z czasem kontrakty mogą ewoluować, ale jednocześnie muszą zachować wsteczną kompatybilność dla istniejących współpracowników. Te sprzeczne dążenia – między stabilnością a zmianą – są trudne do zarządzania.
APLIKACJE MIKROSERWISOWE SĄ PROJEKTOWANE PRZEZ ZESPOŁY
W większych firmach prawdopodobnie wiele zespołów będzie budować i uruchamiać aplikację mikroserwisową, z których każdy będzie odpowiedzialny za różne mikroserwisy. Każdy zespół może mieć własne cele, sposób pracy i cykl życia dostarczania. Projektowanie spójnego systemu może być trudne, gdy trzeba pogodzić harmonogramy i priorytety wielu niezależnych zespołów. Koordynacja rozwoju poważniejszych aplikacji mikroserwisowych będzie zatem wymagać porozumienia i uzgodnienia priorytetów oraz praktyk w wielu zespołach.
APLIKACJE MIKROSERWISOWE SĄ SYSTEMAMI ROZPROSZONYMI
Projektowanie aplikacji mikroserwisowych oznacza projektowanie systemów rozproszonych. W projektowaniu systemów rozproszonych pojawia się wiele błędnych założeń, takich jak:
■ sieć jest niezawodna;
■ opóźnienie jest zerowe;
■ przepustowość jest nieograniczona;
■ koszt transportu jest zerowy.
Założenia, które można zastosować do systemów scentralizowanych, takie jak szybkość i niezawodność wywołań metod, w tych przypadkach są oczywiście nieodpowiednie i mogą prowadzić do złej, niestabilnej implementacji. Należy uwzględnić opóźnienia, niezawodność i spójność stanów w całym obszarze aplikacji.
W aplikacji rozproszonej, gdzie dane o stanie aplikacji są rozmieszczone w wielu miejscach, spójność staje się wyzwaniem. Możemy nie mieć gwarancji kolejności operacji. Nie będzie można zapewnić gwarancji transakcyjnych podobnych do ACID, gdy działania mają miejsce w wielu usługach. Wpłynie to na projektowanie na poziomie aplikacji – należy się zastanowić, w jaki sposób usługa może działać w niespójnym stanie i jak wycofać się w przypadku niepowodzenia transakcji.
1.2.2. Wyzwania związane z działaniem
Podejście mikroserwisowe z natury mnoży możliwe miejsca awarii w systemie. Aby to zilustrować, wróćmy do narzędzia inwestycyjnego, o którym wspominaliśmy wcześniej. Na rysunku 1.6 są wskazane możliwe punkty awarii w tej aplikacji. Łatwo zauważyć, że w wielu miejscach coś może pójść nie tak i może mieć wpływ na normalne przetwarzanie zlecenia.
Zastanówmy się, na jakie pytania należy odpowiedzieć, gdy aplikacja jest na etapie produkcji:
■ Jeśli coś pójdzie nie tak i zlecenie użytkownika nie zostanie złożone, to w jaki sposób ustalimy, gdzie doszło do błędu?
■ Jak wdrożyć nową wersję usługi bez wpływu na składanie zleceń?
■ Skąd wiadomo, które usługi miały zostać wywołane?
■ Jak sprawdzić, czy dane zachowanie działa poprawnie między wieloma usługami?
■ Co się stanie, gdy usługa będzie niedostępna?
Zamiast eliminować ryzyko, mikroserwisy przenoszą te koszty na późniejszy etap cyklu życia systemu – zmniejszają tarcia w rozwoju, ale zwiększają złożoność sposobu wdrażania, weryfikacji i obserwacji działania aplikacji.
Rysunek 1.6. Możliwe punkty awarii przy składaniu zlecenia sprzedaży
Podejście mikroserwisowe sugeruje ewolucyjne podejście do projektowania systemu – umożliwia dodawanie nowych funkcjonalności niezależnie, bez zmiany istniejących usług. Minimalizuje to koszty i ryzyko zmian.
Ale w samodzielnym systemie, który ciągle się zmienia, może być niezwykle trudno śledzić obraz całości, co sprawia, że diagnoza problemu i wsparcie są bardziej kłopotliwe. Kiedy coś pójdzie nie tak, musimy mieć jakiś sposób śledzenia zachowania się systemu (jakie usługi wywołał, w jakiej kolejności, jaki był wynik), ale potrzebujemy również sposobu, aby dowiedzieć się, jak system powinien się zachowywać.
W mikroserwisach zatem napotykamy dwa operacyjne wyzwania: obserwowalność i wiele punktów awarii. Skupmy się na każdym z nich.
OBSERWOWALNOŚĆ JEST TRUDNA DO OSIĄGNIĘCIA
Na znaczenie przejrzystości zwróciliśmy uwagę w punkcie 1.1.2. Ale dlaczego jest to trudniejsze w aplikacjach mikroserwisowych? Jest tak, ponieważ musimy zrozumieć szerszy kontekst. Musimy go zebrać z wielu elementów układanki po to, żeby skorelować i połączyć dane, które generuje każda usługa, aby móc zrozumieć, co każda usługa robi w szerszym kontekście dostarczania wyników biznesowych. Poszczególne dzienniki usług zapewniają częściowy widok na działanie systemu, co jest pomocne, ale do pełnego zrozumienia całości potrzebne są zarówno mikroskop, jak i obiektyw szerokokątny.
Ponadto, ponieważ uruchamiamy wiele aplikacji, w zależności od tego, jak zostały wdrożone, powiązania między podstawowymi parametrami infrastruktury – takimi jak wykorzystanie pamięci i procesora – a aplikacją mogą być mniej oczywiste. Te parametry nadal mogą być użyteczne, ale są mniej przydatne niż mogłyby być w systemie monolitycznym.
ZWIĘKSZANIE LICZBY MIKROSERWISÓW ZWIĘKSZA LICZBĘ PUNKTÓW AWARII
Prawdopodobnie nie będziemy zbytnimi pesymistami, jeśli powiemy, że wszystko, co może zawieść, zawiedzie. Ważne jest, żeby tak o tym myśleć – jeśli założymy słabość i niestabilność usług tworzących nasz system, to ułatwi nam to jego projektowanie, wdrażanie i monitorowanie i nie będziemy zaskoczeni, gdy coś pójdzie nie tak.
Musimy się zastanowić, jak system będzie działał mimo awarii poszczególnych komponentów. Oznacza to, że indywidualne usługi będą musiały być bardziej niezawodne – pod względem sprawdzania błędów, działania w sytuacjach awaryjnych i powrotu do normalnej pracy – ale także to, że cały system powinien działać niezawodnie, nawet jeśli poszczególne komponenty nigdy nie są w 100% niezawodne.
Rysunek 1.7. Kluczowe powtarzane etapy – projekt, wdrażanie i obserwacja – w cyklu życia mikroserwisu
4
SOA jest mętnym terminem. Mimo że wiele zasad SOA jest podobnych do tych dotyczących mikroserwisów, definicja tego pierwszego jest nierozerwalnie związana z dużymi narzędziami dla przedsiębiorstw, takimi jak ESB.