Scott Tiger Tech Blog

Blog technologiczny firmy Scott Tiger S.A.

Mikrousługi w chmurze Amazonu

Autor: Piotr Karpiuk o środa 17. Maj 2017

Architektura mikrousług

Idea mikrousług nie powstała znikąd, obejmuje szereg sprawdzonych koncepcji takich jak programowanie zwinne (ang. agile development), architektura zorientowana na usługi (SOA), podejście API-first czy ciągłe dostarczanie (ang. continuous delivery, CD).

Główne cechy mikrousług:

  • Decentralizacja, zarówno jeśli chodzi o sposób działania (i np. spojrzenie na modele danych), ale również sposób tworzenia.
  • Niezależność – każdy komponent można zmienić niezależnie od pozostałych. Każdy komponent jest też tworzony przez osobny zespół.
  • Mikrousługa robi jedną rzecz, ale dobrze, skupiając się na jednej dziedzinie.
  • Można użyć wiele technologii – każda mikrousługa może być tworzona przy użyciu technologii najlepiej pasującej do dziedziny problemu i umiejętności zespołu.
  • Każda usługa jest czarną skrzynką z dobrze zdefiniowanym API.
  • Zespół który tworzy usługę jest odpowiedzialny za jej wdrożenie i utrzymanie – jest to jedna z najważniejszych zasad DevOps, o tyle istotna że zgodnie z prawem Conwaya architektura systemów tworzonych przez firmę odzwierciedla jej strukturę organizacyjną.

Najważniejsze zalety mikrousług:

  • Zwinność. Mikrousługi sprzyjają organizacji małych niezależnych zespołów przejmujących swoje usługi we władanie. Zespoły działają w obrębie swoich małych i dobrze zrozumiałych światów, co pozwala im skracać cykle produkcji.
  • Innowacja. Wiąże się ze swobodą wyboru technologii, języków programowania i narzędzi do tworzenia każdej usługi. Metodyki zwinne, DevOps i ciągła integracja zachęcają do eksperymentów, które można szybko przetestować i łatwo wycofać w razie niepowodzeń. Niski koszt porażki tworzy kulturę podatną na zmiany i innowacje.
  • Skalowalność i dostępność. Ponieważ mikrousługi są niezależne, można je na produkcji łatwo podmieniać i rozmnażać.

Rzecz jasna nie ma darmowych obiadów i architektura mikrousług ma również swoje wady:

  • Jest to architektura rozproszona, ze wszystkimi wadami. W szczególności nie można założyć że sieć jest niezawodna, opóźnienia komunikacji pomijalne a przepustowość interfejsów sieciowych nieskończona. Architektura mikrousług to problemy z asynchroniczną komunikacją, spójnością danych (transakcje!), odnajdywaniem się mikrousług, czy uwierzytelnianiem komunikacji.
  • Migracja. Przy przejściu z architektury monolitycznej na architekturę mikrousług trzeba podjąć właściwe decyzje dotyczące podziału – wszelkie błędy będą się później srodze mścić.
  • Wersjonowanie. W praktyce często jedna usługa będzie działać w wielu kopiach, ale w różnych wersjach. Trzeba umieć nad tym zapanować.
  • Organizacja. Skuteczne wdrożenie systemów opartych na mikrousługach wymaga często zmian organizacyjnych w firmie, która może być przystosowana do tworzenia oprogramowania w stary sposób.
  • Inne problemy. Każda mikrousługa może być tworzona przy użyciu innych technologii, ale powinien istnieć jakiś spójny mechanizm logowania czy monitorowania takiego systemu – pojawia się pytanie jak uniknąć duplikowania narzędzi i procesów, a także jak to zorganizować żeby nie poświęcać temu zbyt dużo czasu i skupić się na funkcjach biznesowych aplikacji.

Mikrousługi a chmura Amazonu

Chmura obliczeniowa dobrze współgra z mikrousługami – zasoby takie jak moc obliczeniowa są w pełni programowalne i szybko dostępne, w praktyce nie występują ograniczenia zasobów, płacimy tylko za zasoby które rzeczywiście zużywamy (równie łatwo zasoby zwolnić jak przydzielić), co zwalnia nas z potrzeby szacowania lub przewidywania zasobów w przyszłości. Wychodzi to naprzeciw postulatom DevOps, gdzie infrastruktura jest traktowana jako kod (IaC), poddawana jest kontroli wersji i łatwo jest wycofać się do poprzedniej poprawnej konfiguracji. Koszt przeprowadzania eksperymentów wymagających zasobów jest bardzo niski, co sprzyja innowacjom.

Co więcej, chmura Amazonu sama jest zorientowana na usługi. Każda usługa AWS skupia się na jednym dobrze zdefiniowanym praktycznym zagadnieniu i komunikuje się z innymi usługami za pomocą przejrzystego API, co pozwala łatwo składać usługi niemal jak klocki LEGO. Co więcej, często usługi AWS są zarządzane (ang. managed), co oznacza że zwalniają swoich użytkowników z konieczności wykonywania wielu zadań administracyjnych takich jak backupy, konfiguracja skalowania, uodparnianie na awarie, konfiguracja monitorowania, bezpieczeństwa, czy logowanie zdarzeń.

Aby zredukować koszty wdrażania mikrousług, często korzysta się z kontenerów Dockera – w chmurze Amazona odpowiadają za to usługi ECS i ECR. Upraszcza to zarządzanie wersjami komponentów i powrót do poprzednich wersji. ECS eliminuje potrzebę instalowania, administrowania i skalowania własnej infrastruktury klastra. Za pomocą wywołań API możesz łatwo uruchamiać i zatrzymywać swoje aplikacje rozproszone oparte na kontenerach, jak również monitorować ich stan. ECS dobrze współgra również z innymi usługami Amazonu, takimi jak system ról, uprawnień i użytkowników (IAM).

Usługa AWS API Gateway pozwala generować API mikrousług na podstawie definicji Swaggera. API Gateway może robić za drzwi frontowe do dowolnej aplikacji webowej uruchamianej na EC2, ECS, Lambda bądź w lokalnej serwerowni, w razie potrzeby cache’uje zapytania GET, a także loguje wywołania w CloudWatch. Jest w stanie obsłużyć setki tysięcy równoległych wywołań API, nie zapominając o takich aspektach jak zarządzanie ruchem, autoryzacja i uwierzytelnianie, monitorowanie i zarządzanie wersjami API. Obiekt API definiowany w usłudze jest grupą zasobów i metod. Zasób jest obiektem z modelem danych i ewentualnymi powiązaniami z innymi zasobami. Zasób może odpowiadać na wybrane metody HTTP (GET/POST/PUT).

Wykrywanie usług

Możliwe rozwiązania:

  • Application Load Balancing nie tylko równoważy obciążenie serwerów, ale także testuje ich żywotność i automatycznie wyrejestrowuje wadliwe. W połączeniu z możliwościami DNS możemy niskim nakładem zbudować proste rozwiązanie problemu odnajdywania się usług.
  • Route 53 (czyli amazonowa usługa DNS). Funkcja prywatnych hostowanych stref (ang. private hosted zones) pozwala tworzyć rekordy DNS o dostępie ograniczonym do wskazanej podsieci VPC. Rekord SRV zawiera informację o IP, nazwie hosta i porcie mikrousługi. Route 53 pozwala także skonfigurować regularne testowanie żywotności docelowych serwerów aplikacji i reakcję na potencjalną awarię.
  • ECS Event Stream. Możesz podpiąć strumień zdarzeń ECS do CloudWatch i zdefiniować reguły reagujące niemal w czasie rzeczywistym na zdarzenia o zmianie stanu instancji klastra, zatrzymaniu czy wznowieniu kontenera itp. żeby automatycznie zmodyfikować rekordy DNS w Route 53.
  • Narzędzia zarządzania konfiguracją takie jak Chef, Puppet czy Ansible, aczkolwiek pewnym wyzwaniem jest tu częstotliwość testowania żywotności usług i ogólnie logistyka tego zagadnienia aby uniknąć dłuższego przechowywania nieświeżych informacji.
  • NoSQLowa baza klucz-wartość – dobrym przykładem będzie tu usługa DynamoDB.
  • Narzędzia firm trzecich, np. HashiCorp Consul, etcd, czy Netflix Eureka.

Zarządzanie danymi w architekturze rozproszonej

W architekturze mikrousług nie możemy sobie pozwolić na jedną centralną bazę danych jak w aplikacji monolitycznej, ponieważ byłoby to sprzeczne z nadrzędną ideą decentralizacji. Każda mikrousługa powinna mieć własną warstwę trwałego przechowywania danych. Architektury rozproszonych mikrousług poświęcają spójność danych aby zyskać na wydajności (mówimy o docelowej spójności, ang. eventual consistency, co wynika z twierdzenia CAP). Tym niemniej, można sobie wyobrazić centralną bazę danych referencyjnych, z której można odtworzyć bazy danych pozostałych usług.

Często zmiana stanu aplikacji ma swoje odzwierciedlenie w więcej niż jednej mikrousłudze. W takim przypadku dobrze sprawdza się wzorzec o nazwie event sourcing. Idea sprowadza się do reprezentowania każdej zmiany aplikacji jako rekordu zdarzenia. Zamiast zapisywać stan aplikacji, dane są zapisywane jako strumień zdarzeń. Dobre przykłady takiego rozwiązania to logowanie transakcji w relacyjnych bazach danych i systemy kontroli wersji. Event sourcing ma kilka zalet: stan może być odtworzony dla dowolnego punktu w czasie, mamy utrwaloną ścieżkę audytu i ułatwione debugowanie. To rozwiązanie sprzyja rozdzieleniu usług dzięki komunikacji za pomocą wzorca publish/subscribe, i jest często używane w połączeniu ze wzorcem CQRS (Command, Query, Responsibility, Segregation) aby oddzielić procesy odczytujące od zapisujących i optymalizować wydajność, skalowalność i bezpieczeństwo.

Asynchroniczna komunikacja

Oprócz klasycznego REST, mikrousługi mogą się komunikować za pomocą kolejki komunikatów, co ma tę zaletę że nie wymaga wykrywania usług. W świecie AWS za realizację kolejki odpowiada tandem usług SQS i SNS. SNS pozwala wysyłać komunikaty do wielu subskrybentów za pomocą mechanizmu push. Łącząc SQS i SNS można wysłać jeden komunikat do wielu konsumentów.

Rozproszone środowisko mikrousług czyni orkiestrację przepływów dość dużym wyzwaniem. Deweloperzy mogą mieć pokusę aby zaszyć kod orkiestrujący w samych usługach, co nie powinno mieć miejsca ponieważ wiąże ze sobą usługi zbyt mocno. Usługa AWS Step Functions udostępnia maszynę stanów ukrywającą złożoność orkiestracji usług, np. obsługę błędów i serializację/zrównoleglenie. Pozwala to szybko skalować i modyfikować aplikacje przy jednoczesnym unikaniu pisania dodatkowego kodu po stronie usług. Step Functions udostępnia konsolę graficzną pozwalającą aranżować i wizualizować komponenty aplikacji jako serie kroków, co ułatwia budowanie i uruchamianie rozproszonych aplikacji (patrz rysunek).

Step Functions automatycznie uruchamia i śledzi każdy krok, jak również ponawia go w razie błędów, w rezultacie aplikacja wykonuje się zgodnie z oczekiwaniami. Każdy krok jest logowany, co pozwala łatwo diagnozować błędy. Modyfikacja i dodanie kroków odbywa się bez potrzeby pisania kodu, co przyspiesza eksperymenty i ułatwia innowacje. Usługa współpracuje zarówno z komponentami opartymi na EC2, ECS jak i Lambda.

Logowanie i monitoring

W chmurze Amazona do monitorowania zarówno całego ekosystemu AWS, aplikacji jak i pojedynczych komponentów służy usługa CloudWatch. Można definiować własne metryki na użytek aplikacji. Na instancjach EC2 należy zainstalować demona który zrzuca logi do CloudWatch, Lambda robi to automatycznie, a ECS zawiera wsparcie dla sterownika logów awslogs, który pozwala centralizować logi kontenerów w CloudWatch. CloudWatch może uruchamiać alarmy i automatycznie reagować na nie, np. podejmować decyzje o skalowaniu mikrousługi. Domyślnym miejscem składowania logów przez CloudWatch jest S3.

W architekturze rozproszonej często wiele mikrousług musi współpracować aby obsłużyć jedno żądanie. Takie śledzenie komunikacji w logach może być kłopotliwe, zwłaszcza gdy gdzieś pojawi się błąd. Z pomocą przychodzi tu usługa X-Ray, która pozwala taką komunikację zwizualizować (patrz rysunek). Identyfikator żądania jest przekazywany w nagłówku HTTP X-Amzn-Trace-Id.

Logi są często generowane w dużych ilościach i samo ich przetwarzanie (wyszukiwanie, analiza, wizualizacja) staje się wyzwaniem. Z pomocą przychodzi kilka usług chmury Amazonu, które można spiąć z CloudWatch:

CloudTrail to usługa logująca wywołania API usług AWS. Oprócz składowania w S3, można również zażyczyć sobie aby logi te trafiały do CloudWatch.

Dla odmiany, AWS Config inwentaryzuje zasoby AWS, ich konfiguracje, jak również gromadzi historię zmian konfiguracji. Można zdefiniować reguły, które sprawdzają zgodność konfiguracji usług AWS z polityką firmy (np. najlepszymi praktykami dotyczącymi bezpieczeństwa).

Share and Enjoy:
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Śledzik
  • Blip
  • Blogger.com
  • Gadu-Gadu Live
  • LinkedIn
  • MySpace
  • Wykop

Zostaw komentarz

XHTML: Możesz użyć następujących tagów: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>