Czy powinniśmy projektować programy, aby same się zabijały? [Zamknięte]

76

W skrócie, czy powinniśmy projektować śmierć w naszych programach, procesach i wątkach na niskim poziomie, dla dobra całego systemu?

Awarie się zdarzają. Procesy giną. Planujemy katastrofę i od czasu do czasu się z niej odzyskujemy. Ale rzadko projektujemy i wdrażamy nieprzewidywalną śmierć programu. Mamy nadzieję, że przestoje naszych usług będą trwać tak długo, jak długo staramy się je utrzymać.

Makroprzykładem tej koncepcji jest Małpa Chaosu Netflix , która losowo kończy wystąpienia AWS w niektórych scenariuszach. Twierdzą, że pomogło im to odkryć problemy i zbudować więcej zbędnych systemów.

Mówię o niższym poziomie. Chodzi o to, aby tradycyjnie długotrwałe procesy były losowo zamykane. Powinno to wymusić redundancję w projekcie i ostatecznie wytworzyć bardziej odporne systemy.

Czy ta koncepcja ma już nazwę? Czy jest już używany w branży?

EDYTOWAĆ

W oparciu o komentarze i odpowiedzi obawiam się, że moje pytanie nie było jasne. Dla jasności:

  • tak, mam na myśli losowo,
  • tak, mam na myśli w produkcji, i
  • nie, nie tylko do testowania.

Aby wyjaśnić, chciałbym narysować analogię do organizmów wielokomórkowych.

W naturze organizmy składają się z wielu komórek. Komórki rozwidlają się, tworząc nadmiarowość i ostatecznie umierają. Ale zawsze powinno być wystarczającej liczby odpowiednich komórek, aby organizm mógł funkcjonować. Ten wysoce zbędny system ułatwia także gojenie się po zranieniu. Komórki umierają, więc organizm żyje.

Włączenie przypadkowej śmierci do programu zmusiłoby większy system do przyjęcia strategii redundancji, aby pozostały opłacalne. Czy te same strategie pomogłyby systemowi zachować stabilność w obliczu innych nieprzewidzianych awarii?

A jeśli ktoś tego próbował, jak to się nazywa? Chciałbym przeczytać więcej na ten temat, jeśli już istnieje.

jimbo
źródło
13
Nie mam nic przydatnego do udzielenia odpowiedzi, ale jest to zdecydowanie interesujące pytanie. Na pewno zmusiłoby programistę do napisania przyzwoitej architektury komponentów, która (poprawnie) radzi sobie z przypadkowymi awariami komponentów, jeśli te awarie były gwarantowane przez naturę samych komponentów.
Tom W
1
Jeśli dobrze rozumiem, może to być nieco powiązane: en.wikipedia.org/wiki/Mutation_testing . Podczas gdy testowanie mutacji pomaga zaostrzyć testy, myślę, że szukasz podejścia opartego na przypadkowości, które pomogłoby wzmocnić kod.
MetaFight
10
W rzeczywistości ta koncepcja jest tak stara jak informatyka, jest stosowana w każdym programie i oczywiście ma nazwę: nazywa się: błędy .
mouviciel
3
Nie zadzwoniłbyś do testowanej implementacji protokołu komunikacyjnego, gdybyś nie przetestował go w niewiarygodnej sieci, którą należy zasymulować, ponieważ twój sprzęt jest niezawodny.
Kaz
5
Microsoft wypróbował go przez jakiś czas, nazywają go kryptonimem „Windows”. Jeśli stworzył lepsze strategie, można go dyskutować ... mógł zamiast tego wygenerować niższe oczekiwania.

Odpowiedzi:

60

Nie.

Powinniśmy zaprojektować odpowiednią obsługę złej ścieżki i zaprojektować przypadki testowe (i inne ulepszenia procesu), aby sprawdzić, czy programy dobrze radzą sobie z tymi wyjątkowymi warunkami. Rzeczy takie jak Małpa Chaosu mogą być tego częścią, ale gdy tylko ustawisz „musi losowo upaść” wymóg, rzeczywiste losowe awarie stają się tym, czego testerzy nie mogą zgłosić jako błędów.

Telastyn
źródło
10
Dzięki @Telastyn. Wydaje mi się, że przyczyna katastrofy może mieć tutaj znaczenie. Celowa śmierć może mieć efekt uboczny (log, kod błędu, sygnał), który odróżnia go od awarii kodu.
jimbo
1
Nawet jeśli pomaga odkryć słabość, nie oznacza to, że jest wykonalna. Ryzyko (prawdopodobieństwo i stopień konsekwencji) powtórzenia jest istotnym czynnikiem decydującym o tym, czy robisz coś z tym błędem, aby złagodzić przyszłe zdarzenia. Jest to narzędzie wartości długoterminowej dla systemów wysokiego ryzyka.
JustinC
Chodzi o to, że nawet jeśli podzespoły ulegają awarii losowo, użytkownik nie powinien tego zauważyć. Kiedy więc tester zgłasza, że ​​jedna z przypadkowych awarii była dla nich widoczna, oznaczałoby to niepowodzenie wychwytywania awarii podkomponentu, co byłoby błędem w postaci pliku.
Philipp
1
Zaproponowano w rzeczywistości test na żywo obsługi złej ścieżki. Wiele wdrożeń, a przykład Netflix jest tego przykładem, wymaga realistycznych testów obciążenia, które w wielu przypadkach są wykonalne tylko podczas faktycznego wdrożenia. Awarie programowe będą bardzo łatwe do wykrycia dzięki oczywistemu rejestrowaniu - interesujące są uszkodzenia uboczne i wpływ na wzajemnie powiązane systemy.
ctpenrose
1
Możesz zaimplementować inteligentne losowe rozbicie (takie jak Małpa Chaosu), które informuje, kiedy program się losowo zawiesił. W ten sposób wiesz, kiedy trafiłeś w uzasadnioną awarię i kiedy jest to awaria podczas testowania stabilności.
Zain R
19

Proces wprowadzania defektów w oprogramowaniu lub w sprzęcie w celu przetestowania odporności na uszkodzenia mechanizmów nazywa iniekcja błędów .

Z Wikipedii:

Technika wstrzykiwania błędów sięga lat 70. XX wieku, kiedy po raz pierwszy użyto jej do wywołania błędów na poziomie sprzętowym. Ten rodzaj wstrzykiwania błędów nazywa się sprzętowym wprowadzaniem usterki (HWIFI) i próbuje symulować awarie sprzętu w systemie. Pierwsze eksperymenty ze sprzętowym wtryskiem uszkodzeń obejmowały jedynie zwarcie połączeń na płytkach drukowanych i obserwację wpływu na system (uszkodzenia mostkowe). Wykorzystano go przede wszystkim jako test niezawodności systemu sprzętowego. Później opracowano specjalistyczny sprzęt do rozszerzenia tej techniki, taki jak urządzenia do bombardowania określonych obszarów płytki drukowanej silnym promieniowaniem. Szybko stwierdzono, że usterki mogą być wywoływane przez techniki oprogramowania i że aspekty tej techniki mogą być przydatne do oceny systemów oprogramowania.

mouviciel
źródło
+ Pasuje jako test warunków skrajnych drugiego poziomu. Po pomyślnym przejściu wymyślonych testów warunków skrajnych [w zadowalającym stopniu] wstaw losowość, aby zapewnić, że nieoczekiwane zmiany środowiska nie będą katastrofalne. Może być cenny, gdy awaria wiąże się z wysokim ryzykiem (prawdopodobieństwo lub dotkliwość konsekwencji). Nie wdrożyłbym się, aby żyć, dopóki nie byłem bardzo pewny w środowisku laboratoryjnym, a następnie tylko stopniowo w odniesieniu do części, w których byłem najbardziej pewny.
JustinC
9

Tak. Nie, może.

Okresowe zakończenie jest mieczem obosiecznym. Zostaniesz trafiony jedną lub drugą krawędzią, a to, co jest mniejszym z dwóch zła, zależy od twojej sytuacji.

Jedną z zalet jest niezawodność: jeśli zmusisz program do losowego (lub przewidywalnego) zakończenia w uporządkowany sposób, możesz być przygotowany na to wydarzenie i sobie z nim poradzić. Możesz zagwarantować, że proces zakończy się, gdy nie będzie zajęty robieniem czegoś pożytecznego. Gwarantuje to również, że błędy, które ujawnią się po przekroczeniu sankcjonowanego czasu działania, nie odwrócą swoich brzydkich głów podczas produkcji, co jest dobrą rzeczą. Apache HTTPD ma ustawienie, które pozwala dostroić liczbę żądań, które proces potomny (lub wątek w nowszych wersjach) będzie obsługiwał przed zakończeniem.

Drugą zaletą jest także niezawodność: jeśli nie pozwolisz programowi długo działać, nigdy nie znajdziesz błędów, które pojawią się z czasem. Kiedy w końcu napotkasz jeden z tych błędów, znacznie bardziej prawdopodobne jest, że program zwróci złą odpowiedź lub w ogóle jej nie zwróci. Co gorsza, jeśli uruchomisz wiele wątków tego samego zadania, błąd spowodowany czasem lub liczeniem może wpłynąć na bardzo dużą liczbę zadań naraz i spowodować całą podróż do biura o trzeciej nad ranem.

W środowisku, w którym uruchamia się wiele takich samych wątków (np. Na serwerze WWW), praktycznym rozwiązaniem jest zastosowanie podejścia mieszanego, które skutkuje akceptowalnym wskaźnikiem awaryjności. Jeśli uruchomisz 100 wątków, uruchomienie stosunku krótko- i długiego 99: 1 oznacza, że ​​tylko jeden będzie wykazywał błędy długoterminowe, podczas gdy inne będą nadal robić to, co robią, bez porażki. Porównaj to z uruchomieniem 100% długości, gdzie istnieje znacznie większe ryzyko, że wszystkie wątki zawiodą jednocześnie.

Jeśli masz jeden wątek, prawdopodobnie lepiej po prostu pozwolić mu działać i zawieść, ponieważ czas martwy podczas restartu może powodować niepożądane opóźnienia, gdy prawdziwa praca zostanie wykonana pomyślnie.

W obu przypadkach ważne jest, aby było coś nadzorującego procesy, aby można je było natychmiast ponownie uruchomić. Ponadto, nie ma prawa, które mówi, że twoje początkowe decyzje dotyczące tego, jak długo proces powinien trwać, muszą zostać wrzucone w kamień. Zbieranie danych operacyjnych pomoże dostroić system, aby ograniczyć awarie do akceptowalnego poziomu.

Odradzałbym przypadkowe zakończenie, ponieważ utrudnia to ustalanie błędów związanych z czasem. Chaos Monkey robi to, aby upewnić się, że oprogramowanie nadzorujące działa, co jest nieco innym problemem.

Blrfl
źródło
Jeśli zabijesz proces po losowym przedziale czasu, który rozciąga się w nieskończoność, niektóre procesy będą żyć wiecznie. Dlatego nie sądzę, aby losowe zabijanie procesów było niezgodne z wykrywaniem problemów z procesami długotrwałymi.
Joeri Sebrechts,
9

Czy naprawdę masz na myśli przypadek? Losowe zabijanie oprogramowania wydaje się okropnym pomysłem. Jakiemu punktowi to służy?

Zgaduję, że tak naprawdę masz na myśli to, że powinniśmy być realistyczni w kwestii długo działających wątków / procesów i zaakceptować, że im dłużej działają, tym bardziej prawdopodobne jest, że napotkali jakiś ukryty błąd i popadli w niefunkcjonalność stan. Tak więc, jako czysto pragmatyczny środek, żywotność procesów i wątków powinna być ograniczona.

Uważam, że pod koniec lat 90. serwer WWW Apache używał czegoś takiego. Mieli pulę procesów roboczych (nie wątków), a każdy proces roboczy został zabity po określonym czasie życia. Dzięki temu serwer nie został zmonopolizowany przez procesy robocze, które utknęły w stanie patologicznym.

Od jakiegoś czasu nie pracowałem w tej okolicy, więc nie wiem, czy nadal tak jest.

Charles E. Grant
źródło
6
Usługi IIS okresowo uruchamiają się ponownie w interfejsie zarządzania i są domyślnie włączone. Są też wyzwalacze ograniczające pamięć i procesor, ale zależne od czasu zawsze wydawały mi się dziwne.
Mark Brackett,
3
Do dziś rozwiązaniem problemu wycieków pamięci w języku Python jest ponowne uruchomienie procesu.
Xavi
3
Nie sądzę, że OP prosi o zabicie programu, aby przywrócić go do prawidłowo działającego stanu, ale zabić program, aby przetestować zdolność systemu do radzenia sobie z jego śmiercią i do wszelkich późniejszych uruchomień programu do obsługi pozostaje.
mowwwalker
1
@MarkBrackett Niestety okresowe ponowne uruchomienie wydaje się służyć odwrotnemu celowi, ponieważ programiści nie zwracają uwagi na zły kod. Gdyby problemy spowodowane złym kodem były kłopotami z naprawą, mniej prawdopodobne byłoby napisanie złego kodu.
Anthony
+1. Random jest zły. Z definicji jest tak, że nie można przewidzieć jego zachowania. Nawet jeśli umieścisz go tam w celu zamykania programu od czasu do czasu, może się okazać, że po prostu nie da się tego zrobić, ponieważ jest losowy, a zatem nie ma sensu go uruchamiać. Zamknięcie procesów w przewidywalnych momentach może być łatwiejsze dla programisty, a także dla marketera próbującego sprzedać tę konkretną funkcję. „Tak, zgadza się. Zamyka się w przypadkowych momentach! Nie, to funkcja! Cześć? Cześć ?!”
Neil
7

Problem, jaki widzę, polega na tym, że jeśli taki program umrze, powiemy tylko: „Och, to kolejne przypadkowe zakończenie - nie ma się o co martwić”. Ale co jeśli istnieje prawdziwy problem, który wymaga naprawy? Zostanie zignorowany.

Programy już „losowo” zawodzą ze względu na to, że programiści robią mistayki, błędy wprowadzają je do systemów produkcyjnych, awarie sprzętu itp. Gdy to nastąpi, chcemy o tym wiedzieć, abyśmy mogli to naprawić. Projektowanie śmierci w programach tylko zwiększa prawdopodobieństwo niepowodzenia i zmusi nas do zwiększenia nadmiarowości, co kosztuje.

Nie widzę nic złego w przypadkowym zabijaniu procesów w środowisku testowym podczas testowania nadmiarowego systemu (powinno się to zdarzać częściej niż w rzeczywistości), ale nie w środowisku produkcyjnym. Czy wyjmowalibyśmy kilka dysków twardych z systemu produkcji na żywo co kilka dni, czy dezaktywowaliśmy jeden z komputerów w samolocie, który leci pełen pasażerów? W scenariuszu testowym - w porządku. W scenariuszu na żywo - wolałbym nie.

przyciąć
źródło
Jeśli zastosujesz przypadkowe zakończenie, z pewnością wydrukujesz komunikat w dzienniku „teraz kończę”, abyś mógł odróżnić celowe losowe zakończenie od błędów. ;-) Ponadto ponowne uruchomienie jednego z kilku procesów od czasu do czasu nie wymagałoby więcej nadmiaru, tak jak powinieneś.
Hans-Peter Störr
4

Dodanie losowego kodu wyjścia do aplikacji nie powinno być konieczne. Testerzy mogą pisać skrypty, które losowo zabijają procesy aplikacji.

W sieci konieczne jest symulowanie zawodnej sieci w celu przetestowania implementacji protokołu. Nie jest to wbudowane w protokół; może być symulowany na poziomie sterownika urządzenia lub za pomocą zewnętrznego sprzętu.

Nie dodawaj kodu testowego do robienia programu dla sytuacji, które można osiągnąć zewnętrznie.

Jeśli to jest przeznaczone do produkcji, nie mogę uwierzyć, że to poważne!

Po pierwsze, chyba że procesy zakończą się nagle, co spowoduje utratę transakcji w toku i niestabilnych danych, nie jest to uczciwa implementacja tej koncepcji. Planowane, pełne wdzięku wyjścia, nawet jeśli są losowe, nie pomagają odpowiednio przygotować architektury do radzenia sobie z prawdziwymi awariami, które nie są taktowne.

Jeśli w aplikację wbudowane są rzeczywiste lub realistyczne usterki, mogą one spowodować szkody ekonomiczne, podobnie jak rzeczywiste usterki, a celowa szkoda ekonomiczna jest w zasadzie przestępstwem prawie z definicji.

Możesz być w stanie uniknąć klauzul zawartych w umowie licencyjnej, które zwalniają odpowiedzialność cywilną z wszelkich szkód wynikających z działania oprogramowania, ale jeśli szkody te są projektowane, możesz nie być w stanie zrzec się odpowiedzialności karnej.

Nawet nie myśl o takich wyczynach kaskaderskich: spraw, aby działał tak niezawodnie, jak to tylko możliwe, i umieszczaj fałszywe scenariusze awarii tylko w specjalnych kompilacjach lub konfiguracjach.

Kaz
źródło
To powinna być zaakceptowana odpowiedź IMO. Obowiązuje tutaj SRP.
user408866
Niestety nie chodzi mi tylko o testowanie. Rozwinę pytanie, aby wyjaśnić.
jimbo
Jeśli zrobisz to dobrze, te losowe (i nie pełne wdzięku!) Awarie nie wyrządzą żadnej trwałej szkody. O to chodzi: z czasem możesz odrzucić wszystkie skrajne przypadki, w których występuje szkoda; niektórych z nich nigdy nie zobaczysz na testujących maszynach. A jeśli czasami zdarzy się prawdziwa awaria, nie będziesz miał problemów. Nigdy tego nie próbowałem, ale w niektórych okolicznościach wydaje mi się to rozsądne. Oczywiście jest to coś, co musi być oficjalnym cechą aplikacji, a nie coś rozwój wymyka się.
Hans-Peter Storr
3

Możesz szukać „ proaktywnego odzyskiwania ” i „ odmładzania ” w kontekście odpornych na awarie systemów rozproszonych, aby radzić sobie z dowolnymi błędami (tj. Nie tylko zawieszonymi procesami, ale także uszkodzonymi danymi i potencjalnie złośliwym zachowaniem). Przeprowadzono wiele badań dotyczących tego, jak często i w jakich warunkach należy restartować proces (w sensie abstrakcyjnym, może to być maszyna wirtualna lub host). Intuicyjnie możesz zrozumieć zalety tego podejścia, ponieważ wolisz radzić sobie z martwym procesem niż z procesem zdrajcy ...

jop
źródło
2

Tak naprawdę nie różni się to od testowania. Jeśli projektujesz zawsze dostępne rozwiązanie przełączania awaryjnego (takie jak Netflix), to tak - powinieneś je przetestować. Nie wiem jednak, czy przypadkowe wyjścia rozsypane w bazie kodu są odpowiednim sposobem na przetestowanie tego. O ile naprawdę nie zamierzasz testować, czy Twój projekt jest odporny na strzelanie sobie w stopę, bardziej odpowiednie wydaje się przetestowanie go poprzez manipulowanie środowiskiem wokół kodu i sprawdzenie, czy zachowuje się odpowiednio.

Jeśli nie projektujesz nadmiarowych systemów, nie - nie powinieneś dodawać tej funkcji, ponieważ dodałeś kilka losowych wyjść. Powinieneś po prostu usunąć losowe wyjścia, a wtedy nie będziesz miał tego problemu. Twoje środowisko wciąż może zawieść na tobie, w którym to momencie albo zaczniesz pisać, że nie jest ono obsługiwane / nie naprawisz, albo nie zahartujesz kodu przed tym niepowodzeniem i dodasz test. Czy to wystarczająco często, i zdasz sobie sprawę, że rzeczywiście projektowaniu redundantnego systemu - patrz scenariusza # 1.

W pewnym momencie możesz stwierdzić, że nie jesteś już pewien, jakie awarie są lub nie są obsługiwane. Teraz możesz zacząć losowo wyciągać dywan, aby wykryć punkty awarii.

Jedyną interesującą rzeczą w przykładzie Netflix jest to, że uruchamiają te testy w produkcji. To ma pewien sens - niektóre błędy są tak naprawdę produkcyjnymi rzeczami, które są bardzo trudne lub niemożliwe do symulacji w odizolowanym środowisku. Podejrzewam, że Netflix spędził dużo czasu w środowiskach testowych, zanim były wystarczająco wygodne, aby to zrobić w produkcji. I tak naprawdę wszystko, co robią, to próby spowodowania awarii w godzinach pracy, co ma pewien sens dla ich rynku, ale nie dla wielu innych.

Mark Brackett
źródło
2

Termin, którego szukasz, został niedawno ukuty przez Nassima Nicholasa Taleba: Antifragility. Jego książka Antifragile jest zdecydowanie zalecana. Ledwie wspomina o IT, ale niewypowiedziane, oczywiste podobieństwa są najbardziej inspirujące. Jego pomysłem jest rozszerzenie skali kruchej <-> odpornej na delikatną <-> solidną <-> antyfragile. Kruche przerwy z przypadkowymi zdarzeniami, solidne zarządzanie z przypadkowymi zdarzeniami i anty-kruche zyski z przypadkowymi zdarzeniami.

leancz
źródło
1

To zależy. Zauważyłem, że programiści zwykle nadmiernie generalizują techniki stosowane w ich konkretnych domenach, ignorując wszystkie inne. Na przykład wydanie programu kosztem naprawy wszystkich błędów może być dobre ... chyba że zaprogramujesz kontroler statku powietrznego, reaktor jądrowy itp. „Nie optymalizuj - koszt programatora jest większy niż koszt uruchomienia programu” nie jest konieczny ważne dla HPC, ponieważ stosunkowo prosty program może zajmować klaster przez wiele miesięcy itp. (lub nawet popularny program, z którego korzysta duża liczba użytkowników). Więc nawet jeśli firma X robi Y z bardzo dobrego powodu, nie musisz podążać ich śladami, ponieważ Twoja sytuacja może być inna.

Zwykle procedury obsługi błędów są najgorzej przetestowaną częścią kodu - choć wydaje się to proste, trudno jest zasymulować brak wystarczającej ilości pamięci lub brak jakiegoś ważnego pliku. Z tego powodu czytam teksty, które proponowały jądro uniksowe, aby przypadkowo zawiodły niektóre wywołania systemowe. Utrudnia to jednak pisanie prostych programów (jeśli muszę połączyć 3 biblioteki C ++, aby uruchomić program na 2 plikach, gdy nie chcę zawracać sobie głowy obsługą błędów). Nawet z wyjątkami, GC, musisz upewnić się, że pozostawiłeś spójny stan (wyobraź sobie wyjątek w środku dodawania węzła do listy połączonej).

Im więcej usług rozproszonych masz, tym więcej awarii oznacza pytanie „jak często” to „jeśli” lub „kiedy”. W centrach danych wymiana dysków w macierzach RAID stanowi część rutynowych operacji z tego, co wiem - nie jest to nieoczekiwana awaria. Jeśli działasz na dużą skalę, musisz wziąć to pod uwagę, ponieważ nawet jeśli prawdopodobieństwo awarii jednego elementu jest niewielkie, istnieje prawdopodobieństwo, że coś zawiedzie.

Nie wiem, co dokładnie robisz, ale aby wiedzieć, czy warto, musisz pomyśleć, czy porażka jest czymś, co musisz wziąć pod uwagę (ponieważ ignorowanie kosztuje) lub jest zbyt kosztowne, aby analizować (jako uwzględnianie błędów pod uwagę czas opracowania kosztów).

Maciej Piechotka
źródło
„programiści mają tendencję do nadmiernego upowszechniania technik, które mają zastosowanie do ich konkretnej dziedziny”. Chciałbym wykreślić ten cytat i zawiesić go na ścianie. To jest takie prawdziwe, i to nie tylko oprogramowania, ale życia w ogóle.
Mark E. Haase
1

Serwer IIS ma konfigurowalną funkcję, która automatycznie odzyskuje procesy robocze albo po zużyciu określonej ilości pamięci, albo po obsłużeniu określonej liczby żądań lub po upływie określonego czasu. ( http://msdn.microsoft.com/en-us/library/ms525803(v=vs.90).aspx ) i ( http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/ 1652e79e-21f9-4e89-bc4b-c13f894a0cfe.mspx? Mfr = true )

Gdy robi to KONTENER, taki jak IIS, sensowne jest, aby chronić serwer przed nieuczciwymi procesami. Wolałbym jednak wyłączyć tę opcję, ponieważ nie ma sensu, jeśli wystarczająco przetestowałeś swój kod.

Pracujemy już na niewiarygodnych warstwach (sprzęt, sieć), więc nigdy nie napisałbym żadnego kodu, który celowo zabiłby jego wątki lub procesy. Losowe zabijanie jest również złym pomysłem z ekonomicznego punktu widzenia - nikt nie użyłby mojego API, gdyby zorientowali się, że zaprogramowałem go tak, aby losowo się zawiesił. Wreszcie, gdybym miał skonsumować API lub użyć systemu z przypadkowo zawieszającymi się wątkami, musiałbym wydać dużo pieniędzy, aby stworzyć wystarczająco solidny mechanizm monitorowania, aby móc spokojnie spać w nocy.

Zamiast tego Gdybym rozwijał system lub interfejs API, pisałbym skrypty lub korzystałbym z uprzęży, która robiłaby to wyłącznie w celu przetestowania wytrzymałości systemu. I przeprowadziłbym taki test na wszystkich kompilacjach, aby zidentyfikować złe kompilacje. Chociaż byłby to jednak test konieczny, nigdy nie mógłby być testem „wystarczającym”.

użytkownik90766
źródło
1

Istnieje literatura związana z tym pomysłem, zwana oprogramowaniem Crash-Only (również Recovery Oriented Computing) i możesz zacząć od tego papieru usenix Candea & Fox z 2003 roku. Zamiast losowych zabójstw autor twierdzi, że można poprawić niezawodność systemu tylko zawsze zatrzymując swoje programy, zabijając je, więc posiadanie jednego przełącznika „zabicia” jako przycisku wyłączania i pojedynczej dobrze wytrenowanej ścieżki startowej do odzyskiwania.

Chociaż nie jestem pewien, jak dobrze wpadł na ten pomysł, niektóre z konkretnych technik pozostają użyteczne. Na przykład brak zaufania do oprogramowania, które może zamknąć się na żądanie, a więc przy użyciu wyspecjalizowanych programów nadzorczych (np. Superwizja itp.), A także dokładne przemyślenie, jaki stan programu jest niezbędny, i upewnienie się, że zostało zarejestrowane w odpowiednim czasie w zaprojektowanym magazynie danych aby umożliwić odzyskiwanie (np. baza danych SQL).

kzuberi
źródło
2
linki przestarzałe. Twoja odpowiedź byłaby silniejsza, gdybyś streścił kluczowe punkty awarii wyłącznie oprogramowania w swojej odpowiedzi.
1

Naprawdę losowo, nie. Ale prawdopodobnie dobrym pomysłem jest, aby długo działające procesy / wątki wychodziły / restartowały w danym przedziale czasu lub po tym, jak pozostawały bezczynne przez określony (ale zależny od określonych kryteriów) czas trwania lub po wykonaniu określonego rodzaju zadania. Długotrwałe procesy gromadzą się w sposób nieunikniony, włączając w to przestarzałe rzeczy, mogą prawdopodobnie zawiesić się w pamięci, zapobiegając zwolnieniu przestrzeni wymiany, z których wszystkie zostaną (lub powinny zostać) wyczyszczone po wyjściu, poprawiając ogólną stabilność systemu.

RJVB
źródło
1

To zależy od rodzaju projektowanej aplikacji.

Przypadkowe awarie to świetny sposób na przetestowanie i poprawę niezawodności systemów rozproszonych (sieciowych).

W przykładzie Netflix, gdy twój program jest zależny od usług zdalnych, które mogą zawieść z różnych przyczyn, które są poza twoją kontrolą (dysk twardy ulega awarii, utrata zasilania, awaria meteoru w centrum danych itp.). Twoja usługa musi jednak nadal działać.

Jak to robisz? Dodaj nadmiarowość, a skalowanie jest powszechnym rozwiązaniem.

Na przykład, jeśli mysz gryzie kabel zasilający serwera, usługa powinna mieć jakieś rozwiązanie, aby móc dalej działać. Może na przykład zachować nadmiarowe serwery kopii zapasowych, których zacznie używać zamiast tego.

Jeśli jednak twój program jest aplikacją jednoprocesową, która nie działa w sieci, zabicie go nie spowoduje przetestowania niczego, ponieważ nie ma sposobu na odzyskanie go.

Oto dodatkowy komentarz dotyczący koncepcji Chaos Monkeys http://www.codinghorror.com/blog/2011/04/working-with-the-chaos-monkey.html

Zain R.
źródło
1

Możliwe jest, że przypadkowe odwrócenie bitów nastąpi z powodu promieniowania kosmicznego . Problem ten został rozpoznany i opracowano różne techniki , aby zapobiec występowaniu odwracania bitów.

Jednak nie można go naprawić w 100%, a uszkodzenie pamięci może nadal powodować problemy, a problemy te nadal występują ( z bardzo małym prawdopodobieństwem ).

Teraz, aby odpowiedzieć na twoje pytanie. To, czy potrzebujesz zaprojektować bardzo solidny system, zależy od tego, co robisz. Jeśli chcesz stworzyć statek kosmiczny, lepiej uczyń go super wytrzymałym, a wtedy będziesz musiał wziąć pod uwagę każdy możliwy problem.

Jeśli potrzebujesz zaprojektować normalną aplikację komputerową, powinieneś spojrzeć na przypadkowe awarie jako błędy w kodzie.

BЈовић
źródło
0

To nie wydaje się takie niedorzeczne.

System operacyjny Android losowo zabija i ponownie uruchamia aplikacje / usługi użytkownika przez cały czas. Z mojego doświadczenia zdecydowanie pomogło mi to głębiej zastanowić się nad warunkami błędu, a także zaprojektować solidniejsze architektury.

Xavi
źródło
4
Działania Androida nie są losowe, ale działania muszą być w stanie zapisać stan, gdy zostanie im to nakazane. Jest subtelna, ale ważna różnica.
Blrfl
Z tego co czytałem nie ma gwarancji, że onDestroy, onPause, onSaveInstanceState, itd ... nigdy nie można nazwać na działalności lub usługi. Na poziomie aplikacji nie ma nawet onDestoryoddzwaniania. Więc tak, są pewne haki do wdzięcznych wyłączeń, ale wciąż musisz być przygotowany na losowe wyjścia.
Xavi
Masz gwarancję, że zadzwonisz, onPause()zanim aktywność zostanie zabita. Po Honeycomb masz gwarancję, że plus onStop(). Aplikacje na Androida to tylko kolekcje działań, które są ze sobą powiązane i nie ma koncepcji na poziomie aplikacji w zakresie cyklu życia.
Blrfl
Ahh dobrze wiedzieć.
Xavi