Zalecenia dotyczące obsługi błędów przejściowych

Dotyczy tego zalecenia dotyczącego listy kontrolnej niezawodności platformy Azure Well-Architected Framework:

RE:07 Wzmocnienie odporności i możliwości odzyskiwania obciążenia przez zaimplementowanie środków samozachowawczych i samonaprawiania. Twórz możliwości w rozwiązaniu przy użyciu wzorców niezawodności opartych na infrastrukturze i wzorców projektowych opartych na oprogramowaniu w celu obsługi błędów składników i błędów przejściowych. Twórz możliwości w systemie w celu wykrywania awarii składników rozwiązania i automatycznego inicjowania akcji naprawczej, gdy obciążenie nadal działa w pełnej lub ograniczonej funkcjonalności.

Powiązane przewodniki: Zadania w tle | — self-preservation

W tym przewodniku opisano zalecenia dotyczące obsługi błędów przejściowych w aplikacjach w chmurze. Wszystkie aplikacje, które komunikują się ze zdalnymi usługami i zasobami, muszą być wrażliwe na błędy przejściowe. Jest to szczególnie istotne w przypadku aplikacji uruchamianych w chmurze, gdzie ze względu na charakter środowiska i łączności przez Internet ten typ błędu może występować częściej. Przejściowe błędy obejmują chwilową utratę łączności sieciowej ze składnikami i usługami, tymczasową niedostępność usługi i przekroczenia limitu czasu, które występują, gdy usługa jest zajęta. Te błędy są często samonaprawiające, więc jeśli akcja zostanie powtórzona po odpowiednim opóźnieniu, prawdopodobnie zakończy się powodzeniem.

Ten artykuł zawiera ogólne wskazówki dotyczące obsługi błędów przejściowych. Aby uzyskać informacje o obsłudze błędów przejściowych, zobacz wzorzec ponawiania prób i, gdy używasz usług platformy Azure, zobacz Wskazówki dotyczące ponawiania prób dla usług platformy Azure.

Kluczowe strategie projektowania

Błędy przejściowe mogą występować w każdym środowisku, na każdej platformie, w każdym systemie operacyjnym i w każdego rodzaju aplikacji. W przypadku rozwiązań, które działają w lokalnej infrastrukturze lokalnej, wydajność i dostępność aplikacji i jej składników są zwykle utrzymywane za pośrednictwem kosztownej i często niedostatecznej nadmiarowości sprzętowej, a składniki i zasoby znajdują się blisko siebie. Takie podejście sprawia, że awaria jest mniej prawdopodobna, ale nadal mogą wystąpić błędy przejściowe, ponieważ mogą wystąpić awarie spowodowane nieprzewidzianymi zdarzeniami, takimi jak zewnętrzne problemy z zasilaniem lub siecią, lub scenariusze awarii.

Hosting w chmurze, w tym systemy chmury prywatnej, może oferować wyższą ogólną dostępność przy użyciu zasobów udostępnionych, nadmiarowości, automatycznego trybu failover i dynamicznej alokacji zasobów w wielu węzłach obliczeniowych. Jednak ze względu na charakter środowisk w chmurze mogą wystąpić błędy przejściowe. Wynika to z kilku przyczyn:

  • Wiele zasobów w środowisku chmury jest współużytkowanych, a dostęp do tych zasobów podlega ograniczaniu w celu ochrony zasobów. Niektóre usługi odrzucają połączenia, gdy obciążenie wzrośnie do określonego poziomu lub gdy zostanie osiągnięta maksymalna szybkość przepływności, aby umożliwić przetwarzanie istniejących żądań i utrzymać wydajność usługi dla wszystkich użytkowników. Ograniczanie przepustowości pomaga zachować jakość usług dla sąsiadów i innych dzierżaw korzystających z zasobu udostępnionego.

  • Środowiska w chmurze używają dużej liczby towarów jednostek sprzętu. Zapewniają one wydajność dzięki dynamicznej dystrybucji obciążenia między wieloma jednostkami obliczeniowymi i składnikami infrastruktury. Zapewniają one niezawodność przez automatyczne odtwarzanie lub zastępowanie jednostek, które zakończyły się niepowodzeniem. Ze względu na ten dynamiczny charakter błędy przejściowe i tymczasowe błędy połączenia mogą czasami wystąpić.

  • Istnieje często więcej składników sprzętowych, w tym infrastruktury sieciowej, takich jak routery i moduły równoważenia obciążenia, między aplikacją a zasobami i usługami, z których korzysta. Ta dodatkowa infrastruktura może czasami powodować dalsze opóźnienia i przejściowe błędy połączenia.

  • Warunki sieciowe między klientem a serwerem mogą być zmienne, szczególnie w przypadku komunikacji przez Internet. Nawet w lokalizacjach lokalnych duże obciążenia ruchu mogą spowalniać komunikację i powodować sporadyczne błędy połączeń.

Wyzwania

Błędy przejściowe mogą mieć znaczący wpływ na postrzeganą dostępność aplikacji, nawet jeśli zostały dokładnie przetestowane we wszystkich przewidywalnych okolicznościach. Aby zapewnić niezawodne działanie aplikacji hostowanych w chmurze, należy upewnić się, że mogą one reagować na następujące wyzwania:

  • Aplikacja musi mieć możliwość wykrywania błędów, gdy wystąpią, i określić, czy błędy mogą być przejściowe, są długotrwałe lub są błędami terminali. Różne zasoby mogą zwracać różne odpowiedzi w przypadku wystąpienia błędu, a odpowiedzi te mogą również różnić się w zależności od kontekstu operacji. Na przykład odpowiedź na błąd podczas odczytywania aplikacji z magazynu może się różnić od odpowiedzi na błąd podczas zapisywania w magazynie. Wiele zasobów i usług ma dobrze udokumentowane kontrakty na błędy przejściowe. Jednak jeśli takie informacje nie są dostępne, może być trudne do odnalezienia charakteru błędu i tego, czy może to być przejściowe.

  • Aplikacja musi mieć możliwość ponawiania próby wykonania operacji, jeśli ustali, że błąd prawdopodobnie będzie przejściowy. Musi również śledzić liczbę ponownych prób wykonania operacji.

  • Aplikacja musi używać odpowiedniej strategii do ponawiania prób. Strategia określa, ile razy aplikacja powinna ponowić próbę, opóźnienie między poszczególnymi próbami i akcje do wykonania po nieudanej próbie. Odpowiednia liczba prób i opóźnienie między nimi są często trudne do określenia. Strategia różni się w zależności od typu zasobu i bieżących warunków operacyjnych zasobu i aplikacji.

Ogólne wskazówki

Poniższe wskazówki mogą pomóc w zaprojektowaniu odpowiednich mechanizmów obsługi błędów przejściowych dla aplikacji.

Określanie, czy istnieje wbudowany mechanizm ponawiania prób

  • Wiele usług oferuje zestaw SDK lub bibliotekę klienta z mechanizmem obsługi błędów przejściowych. Używane zasady ponawiania są zwykle dostosowane do charakteru oraz wymagań docelowej usługi. Alternatywnie interfejsy REST dla usług mogą zwracać informacje, które mogą pomóc w ustaleniu, czy ponowienie próby jest odpowiednie i jak długo należy poczekać przed następną próbą ponawiania.

  • Należy użyć wbudowanego mechanizmu ponawiania prób, jeśli jest dostępny, chyba że masz określone i zrozumiałe wymagania, które sprawiają, że inne zachowanie ponawiania jest bardziej odpowiednie.

Określanie, czy operacja jest odpowiednia do ponawiania próby

  • Wykonaj operacje ponawiania tylko wtedy, gdy błędy są przejściowe (zwykle wskazywane przez charakter błędu) i gdy istnieje co najmniej pewne prawdopodobieństwo, że operacja zakończy się pomyślnie po ponowieniu próby. Nie ma sensu ponawiać operacji, które próbują wykonać nieprawidłową operację, na przykład aktualizacji bazy danych do elementu, który nie istnieje, lub żądania do usługi lub zasobu, który doznał błędu krytycznego.

  • Ogólnie rzecz biorąc, zaimplementuj ponawianie prób tylko wtedy, gdy można określić pełny efekt tego działania i kiedy warunki są dobrze zrozumiałe i można je zweryfikować. W przeciwnym razie niech wywołanie kodu implementuje ponawianie prób. Pamiętaj, że błędy zwracane z zasobów i usług spoza kontroli mogą ewoluować wraz z upływem czasu i może być konieczne ponowne przejrzenie logiki wykrywania błędów przejściowych.

  • Podczas tworzenia usług lub składników należy rozważyć zaimplementowanie kodów błędów i komunikatów, które pomagają klientom określić, czy powinni ponowić próbę wykonania operacji, które zakończyły się niepowodzeniem. W szczególności wskaż, czy klient powinien ponowić próbę wykonania operacji (na przykład poprzez zwrócenie wartości isTransient ) i zasugerować odpowiednie opóźnienie przed następną próbą ponawiania próby. Jeśli tworzysz usługę internetową, rozważ zwrócenie błędów niestandardowych zdefiniowanych w kontraktach usług. Mimo że klienci ogólną mogą nie być w stanie odczytać tych błędów, są one przydatne podczas tworzenia klientów niestandardowych.

Określanie odpowiedniej liczby ponownych prób i interwału

  • Zoptymalizuj liczbę ponownych prób i interwał do typu przypadku użycia. Jeśli nie ponawiasz próby wystarczająco dużo czasu, aplikacja nie może ukończyć operacji i prawdopodobnie zakończy się niepowodzeniem. Jeśli ponowisz próbę zbyt wiele razy lub z zbyt krótkim interwałem między próbami, aplikacja może przechowywać zasoby, takie jak wątki, połączenia i pamięć przez długi czas, co negatywnie wpływa na kondycję aplikacji.

  • Dostosuj wartości interwału czasu i liczbę ponownych prób do typu operacji. Jeśli na przykład operacja jest częścią interakcji użytkownika, interwał powinien być krótki i należy podjąć tylko kilka ponownych prób. Korzystając z tego podejścia, można uniknąć oczekiwania użytkowników na odpowiedź, która przechowuje otwarte połączenia i może zmniejszyć dostępność dla innych użytkowników. Jeśli operacja jest częścią długotrwałego lub krytycznego przepływu pracy, w którym anulowanie i ponowne uruchomienie procesu jest kosztowne lub czasochłonne, należy poczekać dłużej między próbami i ponowić próbę więcej razy.

  • Należy pamiętać, że określenie odpowiednich interwałów między ponawianiem prób jest najtrudniejszą częścią projektowania udanej strategii. Typowe strategie wykorzystują następujące rodzaje interwałów ponawiania prób:

    • Wycofywanie wykładnicze. Aplikacja czeka chwilę przed pierwszą ponowną próbą, a następnie wykładniczo zwiększa czas między każdym kolejnym ponowieniu próby. Na przykład może ponowić próbę wykonania operacji po 3 sekundach, 12 sekundach, 30 sekundach itd.

    • Interwały przyrostowe. Aplikacja czeka chwilę przed pierwszym ponowieniem próby, a następnie przyrostowo zwiększa czas między kolejnymi ponownymi próbami. Na przykład może ponowić próbę wykonania operacji po 3 sekundach, 7 sekundach, 13 sekundach itd.

    • Interwały regularne. Aplikacja oczekuje stały odstęp czasu między kolejnymi próbami. Na przykład może ponowić próbę wykonania operacji co 3 sekundy.

    • Natychmiastowe ponowienie próby. Czasami błąd przejściowy jest krótki, prawdopodobnie spowodowany przez zdarzenie, takie jak kolizja pakietów sieciowych lub skok w składniku sprzętowym. W takim przypadku natychmiastowe ponawianie próby wykonania operacji jest odpowiednie, ponieważ może się powieść, jeśli błąd zostanie wyczyszczone w czasie potrzebnym aplikacji do złożenia i wysłania następnego żądania. Jednak nigdy nie powinno być więcej niż jednej natychmiastowej próby ponawiania. W przypadku niepowodzenia natychmiastowego ponawiania należy przełączyć się na alternatywne strategie, takie jak wycofywanie wykładniczego lub akcje rezerwowe.

    • Randomizacja. Każda z wymienionych wcześniej strategii ponawiania może zawierać losowe generowanie, aby zapobiec jednoczesnemu wysyłaniu kolejnych prób ponawiania przez wiele wystąpień klienta. Na przykład jedno wystąpienie może ponowić próbę wykonania operacji po 3 sekundach, 11 sekundach, 28 sekundach itd., podczas gdy inne wystąpienie może ponowić próbę wykonania operacji po 4 sekundach, 12 sekundach, 26 sekundach itd. Randomizacja to przydatna technika, którą można połączyć z innymi strategiami.

  • Ogólnie rzecz biorąc, należy użyć strategii wycofywania wykładniczego dla operacji w tle i użyć natychmiastowych lub regularnych strategii ponawiania prób dla operacji interakcyjnych. W obydwu przypadkach należy wybrać opóźnienie i liczbę ponownych prób, tak aby wartość maksymalnego oczekiwania dla wszystkich ponawianych prób kształtowała się w zakresie wymagań dotyczących opóźnień dla połączeń typu end-to-end.

  • Weź pod uwagę kombinację wszystkich czynników, które przyczyniają się do ogólnego maksymalnego limitu czasu dla ponawianej operacji. Czynniki te obejmują czas potrzebny na utworzenie odpowiedzi przez nieudane połączenie (zazwyczaj ustawione przez wartość limitu czasu w kliencie), opóźnienie między ponownymi próbami i maksymalną liczbą ponownych prób. Suma wszystkich tych czasów może spowodować długie ogólne czasy operacji, zwłaszcza w przypadku użycia strategii opóźnienia wykładniczego, w której interwał między ponawiania prób szybko rośnie po każdym niepowodzeniu. Jeśli proces musi spełniać określoną umowę dotyczącą poziomu usług (SLA), całkowity czas operacji, w tym wszystkie limity czasu i opóźnienia, musi mieścić się w granicach zdefiniowanych w umowie SLA.

  • Nie implementuj nadmiernie agresywnych strategii ponawiania prób. Są to strategie, które mają zbyt krótkie interwały lub ponownych prób, które są zbyt częste. Mogą mieć negatywny wpływ na docelowy zasób lub usługę. Te strategie mogą uniemożliwić odzyskanie zasobu lub usługi z przeciążonego stanu i będzie nadal blokować lub odrzucać żądania. Ten scenariusz powoduje błędne koło, w którym coraz więcej żądań jest wysyłanych do zasobu lub usługi. W związku z tym jego zdolność do odzyskania jest jeszcze bardziej ograniczona.

  • Uwzględnij limit czasu operacji podczas wybierania interwałów ponawiania prób, aby uniknąć natychmiastowego uruchomienia kolejnej próby (na przykład jeśli okres przekroczenia limitu czasu jest podobny do interwału ponawiania prób). Należy również rozważyć, czy należy zachować łączny możliwy okres (limit czasu i interwały ponawiania prób) poniżej określonego łącznego czasu. Jeśli operacja ma nietypowo krótki lub długi limit czasu, limit czasu może mieć wpływ na czas oczekiwania i częstotliwość ponawiania próby wykonania operacji.

  • Użyj typu wyjątku i wszelkich danych, które zawiera, lub kodów błędów i komunikatów zwróconych z usługi, aby zoptymalizować liczbę ponownych prób i interwał między nimi. Na przykład niektóre wyjątki lub kody błędów (na przykład kod HTTP 503, usługa niedostępna, z nagłówkiem Retry-After w odpowiedzi) mogą wskazywać, jak długo błąd może trwać lub że usługa nie powiodła się i nie odpowie na żadną kolejną próbę.

  • Rozważ użycie metody kolejki utraconych wiadomości, aby upewnić się, że wszystkie informacje z wywołania przychodzącego nie zostaną utracone po wyczerpaniu wszystkich prób ponowienia próby.

Unikaj wzorców antyszywowych

  • W większości przypadków unikaj implementacji, które obejmują zduplikowane warstwy kodu ponawiania prób. Unikaj projektów, które obejmują kaskadowe mechanizmy ponawiania prób lub które implementują ponawianie na każdym etapie operacji, która obejmuje hierarchię żądań, chyba że masz określone wymagania, które wymagają tego. W tego typu wyjątkowych okolicznościach używaj zasad, które uniemożliwiają stosowanie nadmiernej liczby ponownych prób i zbyt długich czasów opóźnienia oraz upewnij się, że rozumiesz konsekwencje. Załóżmy na przykład, że jeden składnik wysyła żądanie do innej, która następnie uzyskuje dostęp do usługi docelowej. W przypadku zaimplementowania ponawiania próby z liczbą trzech wywołań istnieje dziewięć prób ponawiania próby w sumie względem usługi. Wiele usług i zasobów implementuje wbudowany mechanizm ponawiania prób. Należy zbadać, jak można wyłączyć lub zmodyfikować te mechanizmy, jeśli konieczne jest zaimplementowanie ponownych prób na wyższym poziomie.

  • Nigdy nie implementuj mechanizmu nieskończonego ponawiania prób. W ten sposób może zapobiec odzyskiwaniu zasobów lub usługi z powodu przeciążenia sytuacji i spowodować ograniczanie przepustowości i odrzucanie połączeń, aby kontynuować przez dłuższy czas. Użyj skończonej liczby ponownych prób lub zaimplementuj wzorzec, taki jak wyłącznik , aby umożliwić usłudze odzyskiwanie.

  • Nigdy nie przeprowadzaj natychmiastowego ponawiania próby więcej niż raz.

  • Unikaj regularnego interwału ponawiania prób podczas uzyskiwania dostępu do usług i zasobów na platformie Azure, szczególnie w przypadku dużej liczby ponownych prób. Najlepszym podejściem w tym scenariuszu jest strategia wycofywania wykładniczego z możliwością przerywania obwodu.

  • Zapobiegaj jednoczesnemu wysyłaniu ponownych prób wielu wystąpień tego samego klienta lub wielu wystąpień różnych klientów. Jeśli ten scenariusz prawdopodobnie wystąpi, należy wprowadzić losowość do interwałów ponawiania prób.

Testowanie strategii i implementacji ponawiania prób

  • W pełni przetestuj strategię ponawiania w możliwie najszerszym zakresie, szczególnie w przypadku, gdy aplikacja i docelowe zasoby lub usługi, których używa, są pod skrajnym obciążeniem. Aby sprawdzić zachowanie w trakcie testów:

    • Wstrzykiwanie przejściowych i nieprzejeższych błędów do usługi. Na przykład wyślij nieprawidłowe żądania lub dodaj kod, który wykryje testowe żądania i odpowie za pomocą różnego typu błędów.

    • Utwórz makietę zasobu lub usługi, która zwraca zakres błędów, które może zwrócić rzeczywista usługa. Uwzględnij wszystkie typy błędów, które strategia ponawiania prób została zaprojektowana do wykrywania.

    • W przypadku usług niestandardowych, które tworzysz i wdrażasz, wymuś błędy przejściowe, tymczasowo wyłączając lub przeciążając usługę. (Nie próbuj przeciążać żadnych zasobów udostępnionych ani usług udostępnionych na platformie Azure).

    • Użyj bibliotek lub rozwiązań, które przechwytują i modyfikują ruch sieciowy, aby replikować niekorzystne scenariusze z testów automatycznych. Na przykład testy mogą dodawać dodatkowe czasy przerzucania, upuszczać pakiety, modyfikować nagłówki, a nawet zmieniać treść samego żądania. Umożliwia to deterministyczne testowanie podzestawu warunków awarii w przypadku przejściowych błędów i innych typów awarii.

    • Podczas testowania odporności aplikacji internetowej klienta na błędy przejściowe użyj narzędzi deweloperskich przeglądarki lub możliwości testowania platformy testowania w celu pozorowania lub blokowania żądań sieciowych.

    • Wykonaj testy o wysokim współczynniku obciążenia i współbieżnych, aby upewnić się, że mechanizm ponawiania prób i strategia działają prawidłowo w tych warunkach. Te testy pomagają również zapewnić, że ponawianie próby nie ma negatywnego wpływu na działanie klienta lub powoduje krzyżowe skażenie między żądaniami.

Zarządzanie konfiguracjami zasad ponawiania prób

  • Zasady ponawiania to połączenie wszystkich elementów strategii ponawiania prób. Definiuje mechanizm wykrywania, który określa, czy błąd może być przejściowy, typ interwału do użycia (na przykład regularne, wykładne wycofywanie i losowość), rzeczywiste wartości interwału oraz liczba ponownych prób.

  • Zaimplementuj ponawianie prób w wielu miejscach, nawet w najprostszej aplikacji i w każdej warstwie bardziej złożonych aplikacji. Zamiast kodować trwale elementy poszczególnych zasad w wielu lokalizacjach, rozważ użycie centralnego punktu do przechowywania wszystkich zasad. Można na przykład przechowywać wartości takie jak interwał i liczba ponownych prób w plikach konfiguracji aplikacji, odczytywać je w czasie wykonywania i programowo tworzyć zasady ponawiania prób. Dzięki temu można łatwiej zarządzać ustawieniami i modyfikować i dostosowywać wartości w celu reagowania na zmieniające się wymagania i scenariusze. Jednak należy zaprojektować system do przechowywania wartości zamiast odczytywania pliku konfiguracji za każdym razem i użyć odpowiednich wartości domyślnych, jeśli nie można uzyskać wartości z konfiguracji.

  • Przechowuj wartości używane do tworzenia zasad ponawiania prób w czasie wykonywania w systemie konfiguracji aplikacji, aby można je było zmienić bez konieczności ponownego uruchamiania aplikacji.

  • Korzystaj z wbudowanych lub domyślnych strategii ponawiania, które są dostępne w używanych interfejsach API klienta, ale tylko wtedy, gdy są one odpowiednie dla danego scenariusza. Te strategie są zazwyczaj ogólne. W niektórych scenariuszach mogą to być wszystkie potrzebne, ale w innych scenariuszach nie oferują one pełnego zakresu opcji odpowiadających twoim konkretnym wymaganiom. Aby określić najbardziej odpowiednie wartości, należy przeprowadzić testy, aby zrozumieć, jak ustawienia wpływają na aplikację.

Rejestrowanie i śledzenie przejściowych i nieprzejeższych błędów

  • W ramach strategii ponawiania należy uwzględnić obsługę wyjątków i inną instrumentację, która rejestruje próby ponawiania prób. Oczekiwano sporadycznych niepowodzeń przejściowych i ponawiania prób i nie wskazuje problemu. Regularna i rosnąca liczba ponownych prób często jest jednak wskaźnikiem problemu, który może spowodować awarię lub obniżyć wydajność i dostępność aplikacji.

  • Rejestrowanie przejściowych błędów jako wpisów ostrzegawczych, a nie jako wpisów błędów, dzięki czemu systemy monitorowania nie wykrywają ich jako błędów aplikacji, które mogą wyzwalać fałszywe alerty.

  • Rozważ zapisanie wartości w wpisach dziennika, które wskazują, czy ponawianie prób jest spowodowane ograniczaniem przepustowości w usłudze lub przez inne typy błędów, takich jak błędy połączeń, dzięki czemu można je rozróżnić podczas analizy danych. Wzrost liczby błędów ograniczania dostępności stanowi często wskaźnik wad projektowych aplikacji lub potrzeby przejścia na usługę premium oferującą dedykowany sprzęt.

  • Rozważ pomiar i rejestrowanie ogólnego czasu, który upłynął w przypadku operacji obejmujących mechanizm ponawiania prób. Ta metryka jest dobrym wskaźnikiem ogólnego wpływu błędów przejściowych na czas odpowiedzi użytkownika, opóźnienie procesu i wydajność przypadków użycia aplikacji. Zarejestruj również liczbę ponownych prób, które występują, aby zrozumieć czynniki, które przyczyniają się do czasu odpowiedzi.

  • Rozważ zaimplementowanie systemu telemetrii i monitorowania, który może zgłaszać alerty, gdy liczba i szybkość niepowodzeń, średnia liczba ponownych prób lub ogólny czas, jaki upłynął, zanim operacja zakończy się pomyślnie.

Zarządzanie operacjami, które stale kończą się niepowodzeniem

  • Zastanów się, jak obsługiwać operacje, które nadal kończą się niepowodzeniem przy każdej próbie. Takie sytuacje są nieuniknione.

    • Chociaż strategia ponawiania prób definiuje maksymalną liczbę ponownych prób operacji, nie uniemożliwia aplikacji ponownego powtórzenia operacji przy użyciu tej samej liczby ponownych prób. Jeśli na przykład usługa przetwarzania zamówień zakończy się niepowodzeniem z powodu błędu krytycznego, który trwale go nie działa, strategia ponawiania próby może wykryć przekroczenie limitu czasu połączenia i rozważyć, że jest to błąd przejściowy. Kod ponawia próbę operacji określoną liczbę razy, a następnie rezygnuje. Jednak gdy inny klient składa zamówienie, operacja jest podejmowana ponownie, mimo że za każdym razem zakończy się niepowodzeniem.

    • Aby zapobiec ciągłym ponawianiu prób dla operacji, które stale kończą się niepowodzeniem, należy rozważyć zaimplementowanie wzorca wyłącznika. Jeśli używasz tego wzorca, jeśli liczba niepowodzeń w określonym przedziale czasu przekracza próg, żądania są zwracane do obiektu wywołującego natychmiast jako błędy i nie ma próby uzyskania dostępu do zasobu lub usługi, która zakończyła się niepowodzeniem.

    • Aplikacja może okresowo testować usługę, sporadycznie i z długimi interwałami między żądaniami, aby wykryć, kiedy stanie się dostępna. Odpowiedni interwał zależy od czynników, takich jak krytyczność operacji i charakter usługi. Może to być coś od kilku minut do kilku godzin. Po pomyślnym zakończeniu testu aplikacja może wznowić normalne operacje i przekazać żądania do nowo odzyskanej usługi.

    • W międzyczasie możesz wrócić do innego wystąpienia usługi (być może w innym centrum danych lub aplikacji), użyć podobnej usługi, która oferuje zgodne (może prostsze) funkcje, lub wykonać pewne alternatywne operacje na podstawie nadziei, że usługa będzie dostępna wkrótce. Na przykład może być odpowiednie przechowywanie żądań usługi w kolejce lub magazynie danych i ponawianie ich później. Możesz też przekierować użytkownika do alternatywnego wystąpienia aplikacji, obniżyć wydajność aplikacji, ale nadal oferować akceptowalne funkcje lub po prostu zwrócić komunikat do użytkownika, aby wskazać, że aplikacja nie jest obecnie dostępna.

Inne zagadnienia

  • Podczas podejmowania decyzji o wartościach liczby ponownych prób i interwałach ponawiania próby dla zasad należy rozważyć, czy operacja w usłudze lub zasobie jest częścią długotrwałej lub wieloetapowej operacji. Może to być trudne lub kosztowne, aby zrekompensować wszystkie pozostałe kroki operacyjne, które już zakończyły się pomyślnie, gdy jeden zakończy się niepowodzeniem. W takim przypadku bardzo długi interwał i duża liczba ponownych prób może być akceptowalna, o ile ta strategia nie blokuje innych operacji przez przechowywanie lub blokowanie ograniczonych zasobów.

  • Zastanów się, czy ponawianie próby wykonania tej samej operacji może spowodować niespójności danych. Jeśli niektóre części procesu wieloetapowego są powtarzane, a operacje nie są idempotentne, mogą wystąpić niespójności. Jeśli na przykład operacja zwiększająca wartość jest powtarzana, generuje nieprawidłowy wynik. Powtarzanie operacji, która wysyła komunikat do kolejki, może spowodować niespójność w odbiorcy komunikatów, jeśli użytkownik nie może wykryć zduplikowanych komunikatów. Aby zapobiec tym scenariuszom, zaprojektuj każdy krok jako operację idempotentną. Aby uzyskać więcej informacji, zobacz Wzorce idempotencji.

  • Rozważ zakres operacji, które są ponawiane. Na przykład może być łatwiej zaimplementować kod ponawiania prób na poziomie obejmującym kilka operacji i ponowić próbę ich wszystkich, jeśli jeden zakończy się niepowodzeniem. Może to jednak spowodować problemy z idempotencją lub niepotrzebne operacje wycofywania.

  • Jeśli wybierzesz zakres ponawiania, który obejmuje kilka operacji, uwzględnij całkowite opóźnienie wszystkich z nich podczas określania interwałów ponawiania próby, podczas monitorowania czasu, w którym upłynął czas operacji, oraz przed podniesieniem alertów dotyczących awarii.

  • Zastanów się, jak strategia ponawiania prób może mieć wpływ na sąsiadów i innych dzierżawców w aplikacji udostępnionej oraz w przypadku korzystania z udostępnionych zasobów i usług. Agresywne zasady ponawiania prób mogą powodować wzrost liczby błędów przejściowych dla tych innych użytkowników oraz dla aplikacji, które współdzielą zasoby i usługi. Podobnie aplikacja może mieć wpływ na zasady ponawiania prób zaimplementowane przez innych użytkowników zasobów i usług. W przypadku aplikacji o znaczeniu krytycznym dla działania firmy warto korzystać z usług Premium, które nie są udostępniane. Daje to większą kontrolę nad obciążeniem i konsekwencją ograniczania tych zasobów i usług, co może pomóc w uzasadnieniu dodatkowych kosztów.

Uwaga

Aby uzyskać więcej wskazówek dotyczących kompromisów i czynników ryzyka, zobacz Artykuł Problemy i zagadnienia dotyczące wzorca ponawiania prób.

Ułatwienia platformy Azure

Większość usług platformy Azure i zestawów SDK klienta zapewnia mechanizm ponawiania prób. Jednak te mechanizmy różnią się, ponieważ każda usługa ma różne cechy i wymagania, a każdy mechanizm ponawiania prób jest dostrojony do określonej usługi. W tej sekcji przedstawiono podsumowanie funkcji mechanizmu ponawiania prób dla niektórych często używanych usług platformy Azure.

Usługa Możliwości ponawiania prób Konfiguracja zasad Zakres Funkcje telemetrii
Microsoft Entra ID Natywna w bibliotece uwierzytelniania firmy Microsoft (MSAL) Osadzona w bibliotece MSAL Wewnętrzny Brak
Azure Cosmos DB Natywna w usłudze Brak możliwości konfiguracji Globalnie TraceSource
Azure Data Lake Storage Natywna w kliencie Brak możliwości konfiguracji Poszczególne operacje Brak
Azure Event Hubs Natywna w kliencie Programowa Klient Brak
Azure IoT Hub Natywna w zestawie SDK klienta Programowa Klient Brak
Azure Cache for Redis Natywna w kliencie Programowa Klient TextWriter
Azure Cognitive Search Natywna w kliencie Programowa Klient ETW lub niestandardowy
Azure Service Bus Natywna w kliencie Programowa NamespaceManager, MessagingFactory i client ETW
Azure Service Fabric Natywna w kliencie Programowa Klient Brak
baza danych Azure SQL z ADO.NET Usługa Polly Deklaracyjne i programowe Pojedyncze instrukcje lub bloki kodu Niestandardowy
Usługa SQL Database i platforma Entity Framework Natywna w kliencie Programowa Globalny dla domeny aplikacji Brak
Usługa SQL Database i platforma Entity Framework Core Natywna w kliencie Programowa Globalny dla domeny aplikacji Brak
Azure Storage Natywna w kliencie Programowa Klient i indywidualne operacje TraceSource

Uwaga

W przypadku większości wbudowanych mechanizmów ponawiania prób na platformie Azure obecnie nie ma możliwości zastosowania różnych zasad ponawiania dla różnych typów błędów lub wyjątków. Należy skonfigurować zasady zapewniające optymalną średnią wydajność i dostępność. Jednym ze sposobów dostosowania zasad jest analizowanie plików dziennika w celu określenia typu przejściowych błędów, które występują.

Przykład

Zobacz Wzorzec niezawodnej aplikacji internetowej dla platformy .NET, aby zapoznać się z przykładem, który używa wielu wzorców omówionych w tym artykule. Istnieje również implementacja referencyjna w usłudze GitHub.

Lista kontrolna dotycząca niezawodności

Zapoznaj się z pełnym zestawem zaleceń.