Mikroserwisy na późnym etapie
Czytałem o wysiłkach zespołu Amazon Prime Video w celu skalowania i obniżenia kosztów o 90% poprzez połączenie ich mikrousług w monolit. Chociaż jestem pewien, że jest tu coś więcej, podobne historie są publikowane w Internecie; rodzaj odparcia szaleństwa mikroserwisów ostatniej dekady.
Przypomniało mi to kilka ostatnich lat, które spędziłem na Twitterze, gdzie liczba mikroserwisów (w tysiącach) osiągnęła szczyt, a potem zaczęła spadać, mimo wzrostu ruchu. Wszystkie rodzaje logiki aplikacji zostały wchłonięte przez monolityczne zarządzane platformy tego czy innego rodzaju. Zasada tworzenia specjalnie zaprojektowanych mikrousług nie jest sama w sobie dobra, a po pewnym czasie nie wydawała się również przynosić pozytywnego zwrotu z inwestycji dla wielu naszych zespołów.
Architektura mikrousług może być kosztowna. W ciągu ostatniej dekady pojawiła się narracja, że jest to naturalna polityka dużych organizacji inżynieryjnych, ponieważ:
- Zespoły mogą iterować swoje usługi niezależnie od szerszej organizacji i jej kodu
- Małe komponenty architektury obsługującej mogą być modyfikowane bez zakłócania działania większego systemu
- Architektura pozwala na zdefiniowanie przejrzystych, łatwych w zarządzaniu domen aplikacji i awarii za pośrednictwem niezależnych usług
- Architektura pozwala na niezależnie dostrajane lub skalowalne obciążenia
Należy wziąć pod uwagę złożoność pracy, która jest przenoszona na małe zespoły będące właścicielami usług iw rezultacie na szerszy ekosystem — w przeciwieństwie do pojedynczej lub niewielkiej liczby monolitów. Odciążona praca zależy od dojrzałości stosu technologicznego organizacji; ale może obejmować:
Rozdzielono obowiązki operacyjne i koszty ogólne między wszystkie zespoły będące właścicielami usług
- Zrozumienie i konfiguracja komponentów infrastruktury usługowej, począwszy od narzędzi do planowania zadań i wdrażania, wykrywania usług, struktur RPC, maszyn wirtualnych i powiązanego strojenia, monitorowania usług i rejestrowania
- Rozproszone definicje i procesy rozwoju dla SLO i SLI, obsługa awarii usług i usterek, obsługa przeciwciśnienia i sygnalizacja błędów
- Rozproszone i często nieskoordynowane planowanie pojemności, testowanie obciążenia, wdrażanie testów integracyjnych i obowiązki
- Logika aplikacji, która wchodzi w interakcję z wieloma usługami zaplecza, często porusza się po szeregu niestandardowych definicji API usługi, semantyki, modeli danych, systemów wersjonowania, a czasami nawet różnych protokołów
- Inżynierowie muszą zrozumieć i uzasadnić ogólną architekturę usługi i wzorce ruchu w celu zbudowania funkcjonalnych rzeczy
- Organiczne obejścia dla nieoptymalnych lub wąskich gardeł ścieżek udostępniania, rozproszonej replikacji i zużycia danych, cyklicznych zależności żądań
- Zlokalizowane podejście do problemów wnioskowania i rankingu, przetwarzania zdarzeń, translacji interfejsu API protokołów HTTP/wewnętrznych i mapowania modeli danych
- Ogólna fragmentacja i trudności z utrzymaniem standardów w całym stosie
Problem polega na tym, że proces tworzenia, budowania i operacjonalizacji nowej usługi jest kosztowny . Integracja tej usługi z architekturą obsługującą produkcję jest trudna. Uwaga wymagana do dostrojenia innej usługi do wydajnego działania; skonfigurowanie odpowiednich kont usług, profili obserwowalności i rejestrowania, testów integracyjnych, rotacji dyżurów i wszystkiego innego po prostu zwiększa koszty utrzymania i operacyjne zespołu. W większości organizacji brakuje automatyzacji i kompleksowych rusztowań do tego rodzaju złożonych prac.
Ten narzut jest głównym czynnikiem zniechęcającym zespoły do trzymania się zasady architektury mikroserwisów inspirowanej systemem UNIX: „ rób jedną rzecz dobrze ”. Po prostu łatwiej jest budować nowe przypadki użycia w istniejących usługach. Na najdalszym krańcu spektrum zespoły obsługują usługi „makro”, które zaczynają obejmować wszystko, za co są odpowiedzialne jako zespół, co może obejmować różne produkty lub możliwości. Jakość własności spada z czasem, ponieważ reorganizacje są stosunkowo częstym zjawiskiem. Pracujesz z kulą błota.
Awarie makrousług nie ograniczają się do jednego określonego zestawu funkcji, ale do nieprzewidywalnego lub pozbawionego zasad obszaru systemu, który może przypominać historyczne schematy organizacyjne. Witryna może tolerować niedostępność tych usług lub nie. Trudniej jest zoptymalizować usługi pod kątem heterogenicznych obciążeń; ścieżek połączeń nie można rozplątać. Były kolega wymyślił ten „mikrolit”.
Mikrousługi kodują i zachęcają do lokalnej optymalizacji w architekturze obsługującej. Trudno jest pociągnąć zespoły do odpowiedzialności za pryncypialny projekt służący architekturze, gdy celem jest federacja rozwoju usług. Podobnie trudno jest rozwiązać problemy optymalizacyjne całego zaplecza, gdy właściwości usług zależnych są dostosowane. Bez starannie zaprojektowanej architektury obsługującej i wspierających platform usług trudno jest znaleźć dźwignię — kod platformy produktu wielokrotnego użytku jest rozproszony w szeregu dużych usług lub bibliotek współdzielonych ; usługi frontendowe są zazwyczaj szyte na miarę.
Dźwignia mikrousług została znaleziona w warstwie obliczeniowej (cokolwiek organizuje i wykonuje zadania usług lub kontenery), wykrywaniu usług, maszynie wirtualnej (ma zastosowanie w określonych kontekstach), strukturze usług (takich jak gRPC , Finagle lub Rest.Li ) i scentralizowanych narzędziach programistycznych . Oczywiście siatki serwisowe dobrze obejmują niektóre z tych problemów.
Innym sposobem podejścia do tych problemów jest zmniejszenie narzutu funkcjonalnego. Dlatego zamiast próbować redukować powtarzające się narzuty na infrastrukturę związane z obsługą usługi , można zmniejszyć koszty zespołów ponownie wdrażających wspólne klasy pracy . Właśnie dlatego zarządzane platformy odnoszą taki sukces — nawet jeśli tworzenie lub obsługa usługi jest kosztowna, jeśli uda nam się uszczuplić logikę jej aplikacji poprzez outsourcing do publicznej lub prywatnej platformy zarządzanej, stanie się to mniejszym obciążeniem dla zespołu, który jest jej właścicielem.
Ważne jest, aby organizacje starannie oceniały architektoniczne kompromisy w oparciu o ich specyficzne potrzeby, cele i dojrzałość stosu technologii. Mikroserwisy zapewniają pewne korzyści. Wprowadzają również złożoność i koszty operacyjne, które początkowo wydają się możliwe do opanowania, ale z czasem stają się coraz bardziej złożone. Brak rozwiązania tych problemów sprawia, że kompleksowy proces rozwoju jest niewiele łatwiejszy niż praca w monolicie.
Kilka rzeczy, o których należy pamiętać, zwłaszcza jeśli pracujesz ze starszym mikrolitem:
- „Duże usługi” lub monolity niekoniecznie są złe; wymagają innego rodzaju narzędzi, wsparcia infrastruktury i zestawu zasad niż mikrousługi, ale powinny być budowane tak, aby uchwycić dobrze zdefiniowane wspólne elementy architektury obsługującej
- Opowiadanie się za zasadą „jedno zadanie, jedna usługa” jest zwykle znacznie mniej praktyczne niż wyznaczanie intuicyjnych granic wokół obszarów ścisłej współpracy, problemów związanych z wydajnością i odrębnych domen niepowodzeń — i zmuszanie zespołów do trzymania się planu
- Możesz złagodzić złożoność i koszty ogólne związane ze „zbyt wieloma usługami”, zmniejszając pionową głębokość stosu usług, za który odpowiadają właściciele usług (struktury usług, siatka usług, obliczenia), a także rozpiętość przestrzeni aplikacji za pomocą usług zarządzanych lub platformy dla wspólnych przepływów pracy