Odporność aplikacji i infrastruktury

Ukończone

Odporność to możliwość odzyskania po przejściowych awariach. Strategia odzyskiwania aplikacji przywraca normalną funkcję z minimalnym wpływem użytkownika. Awarie mogą wystąpić w środowiskach chmury, a aplikacja powinna reagować w taki sposób, aby zminimalizować przestoje i utratę danych. W idealnej sytuacji aplikacja bezproblemowo obsługuje błędy bez znajomości problemu przez użytkownika.

Ponieważ środowiska mikrousług mogą być niestabilne, projektuj aplikacje, aby oczekiwały częściowych awarii i obsługiwały je. Na przykład częściowa awaria może obejmować wyjątki kodu, awarie sieci, nieodpowiadania procesów serwera lub awarie sprzętu. Nawet planowane działania, takie jak przenoszenie kontenerów do innego węzła w klastrze Kubernetes, mogą spowodować przejściowy błąd.

Podejścia do odporności

W projektowaniu odpornych aplikacji często trzeba wybrać między szybkim i bezproblemowym obniżeniem wydajności. Szybkie niepowodzenie oznacza, że aplikacja natychmiast zgłosi błąd lub wyjątek, gdy coś pójdzie nie tak, zamiast próbować odzyskać lub obejść problem. Dzięki temu można szybko identyfikować i rozwiązywać problemy. Łagodne obniżenie oznacza, że aplikacja będzie starała się nadal działać w ograniczonej pojemności nawet wtedy, gdy jakiś składnik ulegnie awarii.

W aplikacjach natywnych dla chmury ważne jest, aby usługi obsługiwały błędy bezpiecznie, a nie szybko. Ponieważ mikrousługi są zdecentralizowane i niezależnie wdrażalne, oczekiwane są częściowe awarie. Szybkie niepowodzenie umożliwi awarii w jednej usłudze szybkie wyłączenie usług zależnych, co zmniejsza ogólną odporność systemu. Zamiast tego mikrousługi powinny być kodowane w celu przewidywania i tolerowania zarówno awarii usług wewnętrznych, jak i zewnętrznych. To łagodne obniżenie umożliwia całemu systemowi kontynuowanie działania, nawet jeśli niektóre usługi zostaną zakłócone. Krytyczne funkcje dostępne dla użytkowników mogą być trwałe, co pozwala uniknąć całkowitej awarii. Łaskawa awaria umożliwia również niespokojnym usługom odzyskiwanie lub samoleczenie przed wpływem pozostałej części systemu. Dlatego w przypadku aplikacji opartych na mikrousługach lepsze dopasowanie do najlepszych rozwiązań dotyczących odporności, takich jak izolacja błędów i szybkie odzyskiwanie. Zapobiega to kaskadowym zdarzeniu lokalnym w całym systemie.

Istnieją dwa podstawowe podejścia do zapewnienia bezproblemowego obniżenia odporności: aplikacji i infrastruktury. Każde podejście ma zalety i wady. Oba podejścia mogą być odpowiednie w zależności od sytuacji. W tym module wyjaśniono, jak zaimplementować odporność opartą na kodzie i opartą na infrastrukturze.

Odporność oparta na kodzie

Aby zaimplementować odporność opartą na kodzie, platforma .NET ma bibliotekę rozszerzeń do obsługi odporności i przejściowych awarii. Microsoft.Extensions.Http.Resilience

Używa płynnej, łatwej do zrozumienia składni do tworzenia kodu obsługującego błędy w bezpieczny wątkowo sposób. Istnieje kilka zasad odporności, które definiują zachowanie obsługi niepowodzeń. W tym module zastosujesz strategie ponawiania i wyłącznika do operacji klienta HTTP.

Strategia ponawiania prób

Strategia ponawiania prób jest dokładnie tym, co oznacza nazwa. Żądanie jest ponawiane po krótkim czasie oczekiwania w przypadku otrzymania odpowiedzi na błąd. Czas oczekiwania wzrasta wraz z każdym ponowieniu próby. Wzrost może być liniowy lub wykładniczy.

Po osiągnięciu maksymalnej liczby ponownych prób strategia rezygnuje i zgłasza wyjątek. Z perspektywy użytkownika aplikacja zwykle trwa dłużej, aby wykonać niektóre operacje. Aplikacja może również zająć trochę czasu przed poinformowaniem użytkownika, że nie może ukończyć operacji.

Strategia wyłącznika

Strategia wyłącznika zapewnia usłudze docelowej przerwę po powtarzającej się liczbie awarii, wstrzymując próbę nawiązania z nią komunikacji. Usługa może mieć poważny problem i tymczasowo nie może odpowiedzieć. Po określonej liczbie kolejnych awarii próby połączenia są wstrzymane, otwierając obwód. Podczas tego oczekiwania dodatkowe operacje w usłudze docelowej kończą się niepowodzeniem natychmiast, nawet nie próbując nawiązać połączenia z usługą. Po upływie czasu oczekiwania próba wykonania operacji zostanie ponowiona. Jeśli usługa zostanie pomyślnie zareagowana, obwód zostanie zamknięty , a system wróci do normy.

Odporność oparta na infrastrukturze

Aby zaimplementować odporność opartą na infrastrukturze, można użyć siatki usług. Oprócz odporności bez zmiany kodu, siatka usług zapewnia zarządzanie ruchem, zasady, zabezpieczenia, silną tożsamość i wgląd. Twoja aplikacja jest oddzielona od tych możliwości operacyjnych, które są przenoszone do warstwy infrastruktury.

Porównanie z podejściami opartymi na kodzie

Podejście odporności opartej na infrastrukturze może korzystać z widoku opartego na metrykach, który umożliwia dynamiczne dostosowywanie się do warunków klastra w czasie rzeczywistym. Takie podejście dodaje kolejny wymiar do zarządzania klastrem, ale nie dodaje żadnego kodu.

W przypadku podejścia opartego na kodzie:

  • Koniecznie musisz odgadnąć, które parametry ponawiania i limitu czasu są odpowiednie.
  • Skupić się na konkretnym żądaniu HTTP.

Nie istnieje rozsądny sposób, aby odpowiedzieć na awarię infrastruktury w kodzie aplikacji. Rozważ setki lub tysiące żądań, które są przetwarzane jednocześnie. Nawet ponowienie przy użyciu funkcji wykładniczej (liczba żądań i czas) może zalać usługę.

Z kolei podejścia oparte na infrastrukturze nie wiedzą o wewnętrznych aplikacjach. Na przykład złożone transakcje bazy danych są niewidoczne dla siatki usług. Takie transakcje mogą być chronione tylko przed awarią za pomocą podejścia opartego na kodzie.

W kolejnych lekcjach zaimplementujesz odporność aplikacji opartej na mikrousługach przy użyciu odporności protokołu HTTP platformy .NET w kodzie i siatki usługi Linkerd.