Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Spędziłeś miesiące na przeprojektowaniu swojego monolitu w mikrousługi i wreszcie wszyscy zebrali się, aby zmienić przełącznik. Wchodzisz na pierwszą stronę internetową... i nic się nie dzieje. Ładujesz go ponownie - i znowu nic dobrego, strona działa tak wolno, że nie odpowiada przez kilka minut. Co się stało?

W swoim wykładzie Jimmy Bogard przeprowadzi sekcję zwłok prawdziwej katastrofy mikrousług. Pokaże odkryte przez siebie problemy związane z modelowaniem, rozwojem i produkcją oraz sposób, w jaki jego zespół powoli przekształcał nowy rozproszony monolit w ostateczny obraz zdrowego rozsądku. Chociaż nie da się całkowicie zapobiec błędom projektowym, można przynajmniej zidentyfikować problemy na wczesnym etapie procesu projektowania, aby mieć pewność, że produkt końcowy stanie się niezawodnym systemem rozproszonym.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Witam wszystkich, jestem Jimmy i dzisiaj usłyszycie, jak można uniknąć mega katastrof podczas tworzenia mikroserwisów. Oto historia firmy, dla której pracowałem przez około półtora roku, aby pomóc zapobiec zderzeniu się ich statku z górą lodową. Aby właściwie opowiedzieć tę historię, będziemy musieli cofnąć się w czasie i porozmawiać o tym, gdzie zaczynała się ta firma i jak rozwijała się jej infrastruktura IT na przestrzeni czasu. Aby chronić nazwiska niewinnych osób w tej katastrofie, zmieniłem nazwę tej firmy na Bell Computers. Kolejny slajd pokazuje, jak wyglądała infrastruktura informatyczna takich firm w połowie lat 90-tych. Jest to typowa architektura dużego, uniwersalnego, odpornego na awarie serwera HP Tandem Mainframe do obsługi sklepu ze sprzętem komputerowym.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Musieli zbudować system do zarządzania wszystkimi zamówieniami, sprzedażą, zwrotami, katalogami produktów i bazą klientów, dlatego wybrali najpopularniejsze wówczas rozwiązanie mainframe. Ten gigantyczny system zawierał wszelkie informacje o firmie, wszystko, co było możliwe, a każda transakcja odbywała się za pośrednictwem tego komputera typu mainframe. Trzymali wszystkie jajka w jednym koszyku i uważali, że to normalne. Jedyne, co nie jest tu uwzględnione, to katalogi wysyłkowe i składanie zamówień przez telefon.

Z biegiem czasu system stawał się coraz większy i gromadziła się w nim ogromna ilość śmieci. Poza tym COBOL nie jest najbardziej wyrazistym językiem na świecie, więc system stał się jednym wielkim, monolitycznym śmieciem. Do 2000 roku zobaczyli, że wiele firm ma strony internetowe, za pośrednictwem których prowadzili absolutnie całą swoją działalność, i postanowili zbudować swoją pierwszą komercyjną witrynę internetową.

Początkowy projekt wyglądał całkiem nieźle i składał się z najwyższej klasy witryny bell.com oraz szeregu subdomen dla poszczególnych aplikacji: katalog.bell.com, konta.bell.com, zamówienia.bell.com, wyszukiwanie produktów search.bell. kom. Każda subdomena korzystała ze frameworku ASP.Net 1.0 i własnych baz danych, a także wszystkie komunikowały się z backendem systemu. Jednak wszystkie zamówienia były nadal przetwarzane i realizowane w ramach jednego, ogromnego komputera typu mainframe, w którym pozostały wszystkie śmieci, ale front-end stanowiły osobne strony internetowe z indywidualnymi aplikacjami i oddzielnymi bazami danych.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Zatem projekt systemu wyglądał uporządkowanie i logicznie, ale rzeczywisty system był taki, jak pokazano na następnym slajdzie.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Wszystkie elementy adresowały wzajemne wywołania, dostępne interfejsy API, osadzone biblioteki DLL innych firm i tym podobne. Często zdarzało się, że systemy kontroli wersji chwytały cudzy kod, wrzucały go do projektu i wtedy wszystko się psuło. W MS SQL Server 2005 wykorzystano koncepcję serwerów linkujących i choć nie pokazałem strzałek na slajdzie, to każda z baz danych także ze sobą rozmawiała, bo nie ma nic złego w budowaniu tabel na podstawie danych uzyskanych z kilku baz.

Ponieważ teraz istniała pewna separacja pomiędzy różnymi logicznymi obszarami systemu, stało się to rozproszonymi plamami brudu, przy czym największy kawałek śmieci nadal pozostał w backendie komputera mainframe.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Zabawne było to, że ten komputer mainframe został zbudowany przez konkurentów Bell Computers i nadal był utrzymywany przez ich konsultantów technicznych. Przekonana o niezadowalającym działaniu swoich aplikacji, firma zdecydowała się się ich pozbyć i przeprojektować system.

Istniejąca aplikacja była w produkcji od 15 lat, co jest rekordem wśród aplikacji opartych na ASP.Net. Serwis przyjmował zamówienia z całego świata, a roczny przychód z tej jednej aplikacji sięgał miliarda dolarów. Znaczącą część zysku wygenerował serwis bell.com. W Czarne Piątki liczba zamówień złożonych za pośrednictwem serwisu sięgała kilku milionów. Istniejąca architektura nie pozwalała jednak na rozwój, gdyż sztywne połączenia elementów systemu praktycznie nie pozwalały na wprowadzenie jakichkolwiek zmian w usłudze.

Najpoważniejszym problemem była niemożność złożenia zamówienia z jednego kraju, opłacenia go w innym i wysłania do trzeciego, mimo że taki schemat handlu jest bardzo powszechny w firmach globalnych. Istniejąca strona internetowa nie pozwalała na nic takiego, więc zamówienia trzeba było przyjmować i składać przez telefon. To spowodowało, że firma coraz częściej myślała o zmianie architektury, w szczególności o przejściu na mikroserwisy.

Postąpili mądrze, przyglądając się innym firmom, aby zobaczyć, jak rozwiązały podobny problem. Jednym z takich rozwiązań była architektura usług Netflix, która składa się z mikroserwisów połączonych poprzez API oraz zewnętrzną bazę danych.

Kierownictwo Bell Computers zdecydowało się zbudować właśnie taką architekturę, zachowując pewne podstawowe zasady. Po pierwsze, wyeliminowali duplikację danych, stosując podejście oparte na współdzielonej bazie danych. Nie przesłano żadnych danych, wręcz przeciwnie, każdy, kto ich potrzebował, musiał udać się do scentralizowanego źródła. Potem nastąpiła izolacja i autonomia – każda służba była niezależna od pozostałych. Postanowili wykorzystać Web API do absolutnie wszystkiego - jeśli chciałeś pobrać dane lub dokonać zmian w innym systemie, wszystko odbyło się poprzez Web API. Ostatnią ważną rzeczą był nowy komputer mainframe o nazwie „Bell on Bell”, w przeciwieństwie do komputera typu mainframe „Bell” opartego na sprzęcie konkurencji.

Dlatego w ciągu 18 miesięcy zbudowali system w oparciu o te podstawowe zasady i doprowadzili go do fazy przedprodukcyjnej. Wracając po weekendzie do pracy, programiści zebrali się i włączyli wszystkie serwery, do których podłączony był nowy system. 18 miesięcy pracy, setki programistów, najnowocześniejszy sprzęt Bell – i żadnego pozytywnego rezultatu! Rozczarowało to wiele osób, ponieważ wielokrotnie uruchamiały ten system na swoich laptopach i wszystko było w porządku.

Postąpili mądrze, przeznaczając wszystkie swoje pieniądze na rozwiązanie tego problemu. Zainstalowali najnowocześniejsze szafy serwerowe wraz z przełącznikami, zastosowali gigabitowy światłowód, najpotężniejszy sprzęt serwerowy z niesamowitą ilością pamięci RAM, podłączyli to wszystko, skonfigurowali - i znowu nic! Potem zaczęli podejrzewać, że przyczyną mogą być przekroczenia limitu czasu, więc weszli do wszystkich ustawień sieciowych, wszystkich ustawień API i zaktualizowali całą konfigurację limitu czasu do wartości maksymalnych, tak że jedyne, co mogli zrobić, to siedzieć i czekać, aż coś się wydarzy do serwisu. Czekali, czekali i czekali 9 i pół minuty, aż strona w końcu się załadowała.

Potem dotarło do nich, że obecna sytuacja wymaga dokładnej analizy i zaprosili nas. Pierwszą rzeczą, którą odkryliśmy, było to, że przez wszystkie 18 miesięcy rozwoju nie powstało ani jedno prawdziwe „mikro” – wszystko tylko się powiększyło. Następnie zaczęliśmy pisać sekcję zwłok, zwaną także „regretrospektywą” lub „smutną retrospektywą”, zwaną także „burzą obwiniania”, podobną do „burzy mózgów”, aby zrozumieć przyczynę katastrofy.

Mieliśmy kilka wskazówek, a jedną z nich było całkowite nasycenie ruchem w momencie wywołania API. Korzystając z monolitycznej architektury usług, możesz od razu zrozumieć, co dokładnie poszło nie tak, ponieważ masz pojedynczy ślad stosu, który raportuje wszystko, co mogło spowodować awarię. W przypadku, gdy kilka usług jednocześnie uzyskuje dostęp do tego samego API, nie ma innego sposobu na wyśledzenie śladu, jak tylko użycie dodatkowych narzędzi do monitorowania sieci, takich jak WireShark, dzięki któremu można zbadać pojedyncze żądanie i dowiedzieć się, co wydarzyło się podczas jego realizacji. Wzięliśmy więc jedną stronę internetową i spędziliśmy prawie 2 tygodnie, składając elementy układanki, wykonując różne połączenia i analizując, do czego każdy z nich prowadzi.
Spójrz na ten obrazek. Pokazuje, że jedno żądanie zewnętrzne powoduje, że usługa wykonuje wiele wywołań wewnętrznych, które wracają. Okazuje się, że każde połączenie wewnętrzne wykonuje dodatkowe przeskoki, aby móc samodzielnie obsłużyć to żądanie, gdyż nie może nigdzie indziej zwrócić się po potrzebne informacje. Obraz ten wygląda jak nic nieznacząca kaskada wywołań, gdyż żądanie zewnętrzne wywołuje usługi dodatkowe, które wywołują inne usługi dodatkowe i tak dalej, niemal w nieskończoność.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Kolor zielony na tym diagramie przedstawia półkole, w którym usługi odwołują się do siebie - usługa A wzywa usługę B, usługa B wywołuje usługę C i ponownie wywołuje usługę A. W rezultacie otrzymujemy „rozproszony impas”. Pojedyncze żądanie spowodowało powstanie tysiąca wywołań API sieci, a ponieważ system nie miał wbudowanej odporności na błędy i ochrony przed pętlami, żądanie nie powiedzie się, jeśli choć jedno z tych wywołań API nie powiedzie się.

Zrobiliśmy trochę matematyki. Każde wywołanie API miało umowę SLA nie dłuższą niż 150 ms i czas sprawności 99,9%. Jedno żądanie spowodowało 200 różnych wywołań, a w najlepszym przypadku stronę można było wyświetlić w 200 x 150 ms = 30 sekund. Naturalnie, nie było to nic dobrego. Mnożąc czas sprawności 99,9% przez 200, otrzymaliśmy dostępność 0%. Okazuje się, że architektura ta od początku była skazana na porażkę.

Zapytaliśmy twórców, jak to możliwe, że po 18 miesiącach pracy nie dostrzegli tego problemu? Okazało się, że liczyli SLA tylko za uruchomiony kod, a jeśli ich serwis wzywał inną usługę, nie liczyli tego czasu w swoim SLA. Wszystko, co zostało uruchomione w ramach jednego procesu, trzymało się wartości 150 ms, ale dostęp do innych procesów serwisowych wielokrotnie zwiększał całkowite opóźnienie. Pierwsza lekcja, jaką wyciągnęliśmy, brzmiała: „Czy masz kontrolę nad umową SLA, czy też umowa SLA ma kontrolę nad tobą?” W naszym przypadku było to drugie.

Następną rzeczą, którą odkryliśmy, było to, że wiedzieli o błędnych koncepcjach przetwarzania rozproszonego sformułowanych przez Petera Deitcha i Jamesa Goslinga, ale zignorowali pierwszą jej część. Stwierdza, że ​​stwierdzenia „sieć jest niezawodna”, „zero opóźnień” i „nieskończona przepustowość” są błędnymi przekonaniami. Inne błędne przekonania obejmują stwierdzenia: „sieć jest bezpieczna”, „topologia nigdy się nie zmienia”, „zawsze jest tylko jeden administrator”, „koszt przesyłania danych wynosi zero” oraz „sieć jest jednorodna”.
Popełnili błąd, ponieważ testowali swoje usługi na komputerach lokalnych i nigdy nie łączyli się z usługami zewnętrznymi. Podczas programowania lokalnego i korzystania z lokalnej pamięci podręcznej nigdy nie napotkali przeskoków sieciowych. Przez wszystkie 18 miesięcy rozwoju ani razu nie zastanawiali się, co by się stało, gdyby miało to wpływ na usługi zewnętrzne.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Jeśli spojrzysz na granice usług na poprzednim obrazku, zobaczysz, że wszystkie są nieprawidłowe. Istnieje wiele źródeł, które doradzają, jak zdefiniować granice usług, ale większość robi to źle, jak Microsoft na następnym slajdzie.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

To zdjęcie pochodzi z bloga MS na temat „Jak budować mikrousługi”. To pokazuje prostą aplikację internetową, blok logiki biznesowej i bazę danych. Żądanie przychodzi bezpośrednio, prawdopodobnie jest jeden serwer dla sieci, jeden dla firmy i jeden dla bazy danych. Jeśli zwiększysz ruch, obraz trochę się zmieni.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Oto moduł równoważenia obciążenia do dystrybucji ruchu pomiędzy dwoma serwerami internetowymi, pamięć podręczna zlokalizowana pomiędzy usługą sieciową a logiką biznesową oraz kolejna pamięć podręczna pomiędzy logiką biznesową a bazą danych. Jest to dokładnie ta architektura, której firma Bell użyła w połowie pierwszej dekady XXI wieku w swoich aplikacjach do równoważenia obciążenia i wdrażania rozwiązań niebieskich/zielonych. Do pewnego czasu wszystko działało dobrze, ponieważ ten schemat był przeznaczony dla konstrukcji monolitycznej.

Poniższy rysunek pokazuje, jak firma MS zaleca przejście od monolitu do mikrousług – po prostu dzieląc każdą z głównych usług na osobne mikrousługi. To właśnie podczas wdrażania tego schematu Bell popełnił błąd.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Podzielili wszystkie swoje usługi na różne poziomy, z których każdy składał się z wielu indywidualnych usług. Na przykład usługa internetowa zawierała mikrousługi do renderowania treści i uwierzytelniania, usługa logiki biznesowej składała się z mikrousług do przetwarzania zamówień i informacji o koncie, baza danych została podzielona na kilka mikrousług ze specjalistycznymi danymi. Zarówno sieć WWW, logika biznesowa, jak i baza danych były usługami bezstanowymi.

Jednak obraz ten był całkowicie błędny, ponieważ nie mapował żadnych jednostek biznesowych poza klastrem IT firmy. Schemat ten nie uwzględniał żadnego powiązania ze światem zewnętrznym, więc nie było jasne, w jaki sposób można uzyskać na przykład analizy biznesowe stron trzecich. Zaznaczam, że wymyślili też kilka usług, które miały po prostu rozwijać kariery poszczególnych pracowników, którzy starali się zarządzać jak największą liczbą osób, aby uzyskać za to więcej pieniędzy.

Wierzyli, że przejście na mikrousługi jest tak proste, jak przeniesienie wewnętrznej infrastruktury warstwy fizycznej N-warstwowej i umieszczenie na niej Dockera. Przyjrzyjmy się, jak wygląda tradycyjna architektura N-warstwowa.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Składa się z 4 poziomów: poziomu interfejsu użytkownika UI, poziomu logiki biznesowej, poziomu dostępu do danych i bazy danych. Bardziej postępowa jest architektura DDD (Domain-Driven Design), czyli architektura zorientowana na oprogramowanie, w której dwa środkowe poziomy to obiekty domeny i repozytorium.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Próbowałem przyjrzeć się różnym obszarom zmian, różnym obszarom odpowiedzialności w tej architekturze. W typowym zastosowaniu N-warstwowym klasyfikowane są różne obszary zmian, które przenikają konstrukcję pionowo od góry do dołu. Są to ustawienia katalogu, konfiguracji przeprowadzone na poszczególnych komputerach oraz kontrole w ramach usługi Checkout, którymi zajmował się mój zespół.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Osobliwością tego schematu jest to, że granice tych obszarów zmian wpływają nie tylko na poziom logiki biznesowej, ale także rozciągają się na bazę danych.

Przyjrzyjmy się, co to znaczy być służbą. Definicja usługi ma 6 charakterystycznych właściwości – jest to oprogramowanie, które:

  • stworzone i wykorzystywane przez konkretną organizację;
  • jest odpowiedzialny za treść, przetwarzanie i/lub dostarczanie określonego rodzaju informacji w ramach systemu;
  • można je zbudować, wdrożyć i uruchomić niezależnie, aby spełnić określone potrzeby operacyjne;
  • komunikuje się z konsumentami i innymi usługami, przekazując informacje na podstawie umów lub gwarancji umownych;
  • chroni się przed nieuprawnionym dostępem, a zawarte w nim informacje przed utratą;
  • radzi sobie z awariami w taki sposób, aby nie powodowały one uszkodzeń informacji.

Wszystkie te właściwości można wyrazić jednym słowem „autonomia”. Służby działają niezależnie od siebie, spełniają pewne ograniczenia i określają umowy, na podstawie których ludzie mogą otrzymać potrzebne im informacje. Nie wspomniałem o konkretnych technologiach, których zastosowanie jest oczywiste.

Przyjrzyjmy się teraz definicji mikrousług:

  • mikrousługa jest niewielka i zaprojektowana w celu rozwiązania jednego konkretnego problemu;
  • Mikroserwis jest autonomiczny;
  • Podczas tworzenia architektury mikrousługowej używana jest metafora urbanistyczna. To jest definicja z książki Sama Newmana Building Microservices.

Definicja ograniczonego kontekstu została zaczerpnięta z książki Erica Evansa Domain-Driven Design. Jest to podstawowy wzorzec w DDD, centrum projektowania architektury, które pracuje z wolumetrycznymi modelami architektonicznymi, dzieląc je na różne ograniczone konteksty i wyraźnie definiując interakcje między nimi.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Mówiąc najprościej, kontekst ograniczony oznacza zakres, w jakim można użyć konkretnego modułu. W tym kontekście istnieje logicznie ujednolicony model, który można zobaczyć na przykład w Twojej domenie biznesowej. Jeśli zapytasz personel zajmujący się zamówieniami „kim jest klient”, otrzymasz jedną definicję, jeśli zapytasz osoby zajmujące się sprzedażą, otrzymasz inną, a wykonawcy podadzą trzecią definicję.

Bounded Context mówi więc, że jeśli nie możemy podać jasnej definicji tego, kim jest konsument naszych usług, zdefiniujmy granice, w ramach których możemy rozmawiać o znaczeniu tego terminu, a następnie określmy punkty przejścia pomiędzy tymi różnymi definicjami. Oznacza to, że jeśli mówimy o kliencie z punktu widzenia składania zamówień, to oznacza to i tamto, a jeśli z punktu widzenia sprzedaży, oznacza to to i tamto.

Kolejną definicją mikrousługi jest hermetyzacja wszelkiego rodzaju operacji wewnętrznych, zapobiegająca „wyciekowi” komponentów procesu pracy do środowiska. Następna jest „definicja wyraźnych umów dotyczących interakcji zewnętrznych, czyli komunikacji zewnętrznej”, która jest reprezentowana przez ideę umów powracających z SLA. Ostatnia definicja to metafora komórki, czyli komórki, co oznacza całkowite zamknięcie zestawu operacji w ramach mikroserwisu i obecność w nim receptorów służących do komunikacji ze światem zewnętrznym.

Konferencja NDC w Londynie. Zapobieganie awariom mikrousług. Część 1

Powiedzieliśmy więc chłopakom z Bell Computers: „Nie możemy naprawić chaosu, który stworzyliście, ponieważ po prostu nie macie na to pieniędzy, ale naprawimy tylko jedną usługę, aby wszystko było sens." W tym miejscu zacznę od opowiedzenia, jak naprawiliśmy naszą jedyną usługę, tak aby odpowiadała na żądania szybciej niż 9 i pół minuty.

22:30 min

Ciąg dalszy już wkrótce...

Niektóre reklamy

Dziękujemy za pobyt z nami. Podobają Ci się nasze artykuły? Chcesz zobaczyć więcej ciekawych treści? Wesprzyj nas składając zamówienie lub polecając znajomym, VPS w chmurze dla programistów od 4.99 USD, unikalny odpowiednik serwerów klasy podstawowej, który został przez nas wymyślony dla Ciebie: Cała prawda o VPS (KVM) E5-2697 v3 (6 rdzeni) 10GB DDR4 480GB SSD 1Gbps od 19$ czyli jak udostępnić serwer? (dostępne z RAID1 i RAID10, do 24 rdzeni i do 40 GB DDR4).

Dell R730xd 2 razy taniej w centrum danych Equinix Tier IV w Amsterdamie? Tylko tutaj 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6 GHz 14C 64 GB DDR4 4x960 GB SSD 1 Gb/s 100 Telewizor od 199 USD w Holandii! Dell R420 — 2x E5-2430 2.2 GHz 6C 128 GB DDR3 2x960 GB SSD 1 Gb/s 100 TB — od 99 USD! Czytać o Jak zbudować firmę infrastrukturalną klasy z wykorzystaniem serwerów Dell R730xd E5-2650 v4 o wartości 9000 euro za grosz?

Źródło: www.habr.com

Dodaj komentarz