Budowanie systemów bardziej Resilient

0

Cześć,

w pracy dyskutowaliśmy, sprzeczaliśmy się na temat wykorzystywania wzorców, praktyk, które pomagają obsługiwać sytuacje nieprzewidzianych warunków, wyjątków, błędów w kontekście zewnętrznych integracji głównie REST, Rabbit Pub/Sub, Rabbit RPC. w zależności od sytuacji w postaci retry, timeout, circuit breaker pattern, których jestem nie ukrywam dużym zwolenikiem. Natomiast koledzy zespołu nie bardzo, dodam, że mam niespełna dwa lata doświdczenia w jednym projekcie, koledzy +10.

Dziś zostałem przegłosowany, a argumenty wyglądały w następujący sposób (Z - Zespół, J - Moja osoba) w kontekście Rabbita RPC, polityki Retry, opakowującej wszystkie tzw. Call RPC.

Rozmowa wygląda w ten sposób:

Z - Polityka jest za bardzo generyczna, Co gdybym nie chciał w innej integracji wykorzystującej RPC, polityka będzie nadmiarowa.
J - Bez problemów możemy wykorzystać strategie, które per dziedzina integracji będzie przygtowywać odpowiednią politykę z inną ilością prób ponowienia, konfiguracji etc.
Z - Dla mnie ten kod jest nadmiarowy, dopóki nie będzie takich problemów z konkretną integracją, nie powiniśmy pisać kodu na przyszłość.
J - Na tym polega, wykorzystywanie wzorców pomagając budować systemu odporne na błędy, by być wcześniej przygotowanym a napisanie polityki z wkorzystaniem dzisiejszych bibliotek z testami to godzina pracy. Pasuje to do metafory "zapnę pasy dopiero, jak się rozbije", dlatego też widzę pozytywy w stosowaniu takich mechanizmów.
Z - Z mojego doświadczenia to historycznie wszelkie mechanizmy nie działały, nie sprawdzały się, zawsze błędy zaskakiwały nas przypadki, które ciężko było przewidzieć.
J - W systemie nie wykorzystujemy powyższych mechanizmów, dla mnie dopóki z nich nie skorzystamy, z mojej perspektywy na pewno mogą pomóc, nie zaszkodzić.

W tym tonie przeszła cała dyskusja. Koniec końców zmusili mnie do usunięcia kodu.

A jaka jest Wasza opinia z korzystania powyższych praktyk w systemach monolitycznych, przy zewnętrznych integracjach ?

2

Jeżeli osoby 10+ takich rzeczy nie rozumieją, to zmień pokój ;)

Co do resilency, z doświadczenia wiem, że nie warto wpinać retry zbyt szybko, bo przy mikroserwisach i wielu instancjach może szybko spowodować DDoS'a, które przy małej niedostępności, czy problemach w upstreamie, może te problemy jeszcze nasilić.

Co do timeout, domyślnie jest czekanie w nieskończoność wg kolegów?

Circuit breaker jest dobry, gdy mamy coś opcjonalnego, np Redisa - jak chwile nie działa, to go wyłączyć, ale odwrotnie niż z retry, powinno być domyślnie wszędzie, i na rozłączenie powinno zapisać gdzieś requesty do momentu, gdy można je wysłać, i do tego maila do deva "NIE DZIAŁA" ;)

1

@sharper_99:
skąd wziąłeś te argumenty?

13

@sharper_99 kwestia pragmatyki. Jeśli piszesz coś co ma mieć SLA 99.9999% to piszesz inny kod, niż kiedy robicie coś co może np. mieć downtime przez weekend ;) Podobnie jak możesz np. upisać się jak głupi żeby obsługiwać wiele nodów aplikacji za jakimiś load balancerami, replikacje stanu, rozproszone cache itd, a możesz postawic jedną potężną maszynę bo SLA pozwala na downtime przy restarcie :) Nie zawsze over-engineering jest wskazany. Nie każdy jest Googlem czy AWSem.

Moja rada z serii "jak się takie sytuacje ogarnia w korpo": Napisz szczegółowe minutki ze spotkania - co było omawiane, kto się wypowiadał, jakie padły argumenty itd i na koniec jakie są konkluzje i akcje po tym spotkaniu. Następnie takie minutki rozpropaguj. I teraz jeśli coś wreszcie jebnie ze względu na brak fallbacków to będziesz miał ładny dupochron i szpile do wbicia reszcie zespołu.

3

Implementuj tyle ile musisz, nie pisz wiecej kodu niz potrzeba, Pisz kod, aby dalo sie go rozbudowac, ale jesli kawalek kodu nie jest teraz nikomu potrzebny to po prostu go nie pisz, bo potem tylko trzeba bedzie go utrzymywac, a skoro nie ma gwarancji ze bedzie on potrzebny to po co marnowac czas na jego pisanie, testowanie, i pozniejsze utrzymanie??

To samo z resilency, skoro nie potrzebujecie super HA systemu to moze sa prostsze sposoby aby osiagnac to co chcecie? Ja bym zaczal od monitoringu i wyznaczenia problemow z aplikacja i wtedy zacznijcie prioretyzowac co trzeba zrobic, a nie rozpoczynajcie rozmowy od tego jakie wzorce stosowac... Bo moze polowa z rzeczy o ktorych rozmawiacie nie maja racji bytu w systemie ktory piszecie...

W systemach komercyjnych, fancy systemy nic nie daja, uzywa sie to co znaja ludzie, i w czym sa w stanie napisac stabilny system, to ze uzyjesz RPC calli, kilku nowych bibliotek i bedziesz chcial przepisac polowe systemu, nie przyniesie dla waszego zespolu nic dobrego, lepiej sobie wyznaczcie mniejsze kroki i najpierw zacznij od mniejszych rzeczy...

Dlaczego osoby z 10 letnim doswiadczeniem mialy by Ci wierzyc na slowo ze w ich systemie sprawdzi sie Twoje rozwiazanie, skoro nic nie udowodniles, a jak wiadomo krowa co duzo ryczy, z reguly malo mleka daje :) Nie mowie ze w Twoim przypadku tak jest ale zacznij od mniejszych rzeczy niz przeprojektowywanie systemu.

3

@sharper_99 : Możesz wymienić 3 (2? 1?) konkretne problemy, które zostaną rozwiązane w Waszym projekcie, po wprowadzeniu mechanizmu typu retry?

1

@yarel:

W wiekszości przypadków staramy się by mimo problemów z integracją, użytkownik miał możliwość ponownego odpalenia integracji gdy dane są niezbędne do dalszego procesowania, by nie zablokować procesu biznesowego. Rzeczywiście w tym przypadkach zgadzam się uzysk był by mały, polegał by na udogodnieniu, użytkownik nie miał by świadomości, że nie udało się pobrać danych za pierwszym razem, w zamian otrzymał by stosowny komunikat oraz możliwość ręcznego ponownego pobrania danych. Natomiast mamy w systemie miejscia, gdzie z powodów biznesowych, odpalenie ponownej integracji, wiąże się z cofnięciem się w procesie, zazwyczaj użytkownik, jeżeli nigdy wcześniej nie zablokował się w tym miejscu, szuka pomocy na help desku. Po drugiej stronie mamy klienta, który potencjalnie, jeżeli byłby bardzo nerowowy, mogłby udać się do konkurencji :)

Odnośnie do DDos integracji via Rabbit RPC w naszym systemie to ilość na poziomie ~10. Mechanizm ten miał odpalać się maksymalnie w 3 próbach.
Nie przemawia do mnie ten argument, iż najprostszy mechanizm retry jest kodem na zapas i trzeba go później specjalnie utrzymywać, implementować go dopiero gdy wystąpią problemy, mimo tego, żę w gruncie rzeczy, jest szansa, że nigdy nie wykorzystany może system zewnętrzny jest tak pięknie napisany, sieć jest tak niezawodna, że nigdy nie będzie potrzeby odpalenia tego mechanizmu, wierzycie w to, bo ja nie. Natomiast tak jak @Shalom napisał, system padnie, użytkownik zablokuje się w procesie, przecież nikt nie zginie z tego powodu.

0

Kwestia zważenia ryzyk - jakie jest prawdopodobieństwo wystąpienia, jakie są straty i jaki jest koszt mitygacji. Na tej podstawie można zadecydować, czy pewne rzeczy warto robić. W którymś kroku się rozmijacie w zespole albo już na poziomie interpretacji.

1 użytkowników online, w tym zalogowanych: 0, gości: 1