Sollten wir Programme entwerfen, die sich nach dem Zufallsprinzip selbst töten? [geschlossen]


76

Kurz gesagt, sollten wir den Tod in unseren Programmen, Prozessen und Threads auf einer niedrigen Ebene zum Wohle des Gesamtsystems auslegen?

Fehler passieren. Prozesse sterben. Wir planen eine Katastrophe und erholen uns gelegentlich davon. Aber wir entwerfen und implementieren selten unvorhersehbaren Programmtod. Wir hoffen, dass die Betriebszeiten unserer Services so lange sind, wie wir sie am Laufen halten möchten.

Ein Makrobeispiel für dieses Konzept ist der Chaos Monkey von Netflix , mit dem AWS-Instanzen in einigen Szenarien zufällig beendet werden. Sie behaupten, dies habe ihnen geholfen, Probleme zu entdecken und redundantere Systeme aufzubauen.

Ich spreche von einer niedrigeren Ebene. Die Idee ist, dass traditionell lange laufende Prozesse zufällig beendet werden. Dies sollte eine Redundanz im Entwurf erzwingen und letztendlich stabilere Systeme erzeugen.

Hat dieses Konzept schon einen Namen? Wird es bereits in der Industrie eingesetzt?

BEARBEITEN

Aufgrund der Kommentare und Antworten fürchte ich, dass ich in meiner Frage nicht klar war. Zur Klarheit:

  • ja, ich meine zufällig,
  • ja, ich meine in der Produktion und
  • nein, nicht nur zum testen.

Zur Erklärung möchte ich eine Analogie zu mehrzelligen Organismen ziehen.

Organismen bestehen in der Natur aus vielen Zellen. Die Zellen verzweigen sich, um Redundanz zu erzeugen, und sterben schließlich ab. Es sollten jedoch immer genügend Zellen der richtigen Art vorhanden sein, damit der Organismus funktionieren kann. Dieses hochredundante System erleichtert auch die Heilung bei Verletzungen. Die Zellen sterben, damit der Organismus lebt.

Die Einbeziehung des zufälligen Todes in ein Programm würde das größere System zwingen, Redundanzstrategien anzuwenden, um lebensfähig zu bleiben. Würden dieselben Strategien dazu beitragen, dass das System auch bei anderen Arten von unvorhersehbaren Fehlern stabil bleibt?

Und wenn jemand dies versucht hat, wie heißt es? Ich würde gerne mehr darüber lesen, wenn es bereits existiert.


13
Ich habe nichts Nützliches als Antwort, aber dies ist definitiv eine interessante Frage. Es würde einen Programmierer definitiv zwingen, eine anständige Komponentenarchitektur zu schreiben, die (korrekt) mit zufälligen Komponentenfehlern fertig wird, wenn diese Fehler durch die Art der Komponenten selbst garantiert würden.
Tom W

1
Wenn ich es richtig verstehe, kann dies leicht zusammenhängen: en.wikipedia.org/wiki/Mutation_testing . Während Mutationstests dabei helfen, Ihre Tests zu verbessern, suchen Sie nach einem zufallsbasierten Ansatz, um Ihren Code zu verbessern.
MetaFight

10
Eigentlich ist dieses Konzept so alt wie das Rechnen, es wird in jedem Programm verwendet und hat natürlich einen Namen: es heißt: Bugs .
Mouviciel

3
Sie würden eine getestete Kommunikationsprotokollimplementierung nicht aufrufen, wenn Sie sie nicht über ein unzuverlässiges Netzwerk testen würden, das simuliert werden muss, da Ihre Geräte zuverlässig sind.
Kaz

5
Microsoft hat es eine Weile versucht, sie nennen es mit dem Codenamen "Windows". Wenn es bessere Strategien hervorgebracht hat, ist fraglich ... es könnte stattdessen niedrigere Erwartungen hervorgebracht haben.

Antworten:


60

Nein.

Wir sollten eine ordnungsgemäße Behandlung fehlerhafter Pfade entwerfen und Testfälle (und andere Prozessverbesserungen) entwerfen, um zu validieren, dass Programme mit diesen außergewöhnlichen Bedingungen gut umgehen. Sachen wie Chaos Monkey können ein Teil davon sein, aber sobald man "willkürlich abstürzen lassen" muss, werden tatsächliche zufällige Abstürze zu Dingen, die Tester nicht als Bugs melden können.


10
Vielen Dank @Telastyn. Die Ursache des Absturzes könnte hier eine Rolle spielen, denke ich. Ein absichtlicher Absturz kann eine Nebenwirkung (Protokoll, Fehlercode, Signal) haben, die ihn von einem Codefehler unterscheidet.
Jimbo

1
Selbst wenn es dabei hilft, eine Schwäche aufzudecken, bedeutet dies nicht, dass es umsetzbar ist. Das Risiko (Wahrscheinlichkeit und Grad der Konsequenz) von Wiederholungen ist ein wesentlicher Faktor dafür, ob Sie mit diesem Fehler etwas unternehmen, um das zukünftige Auftreten zu mindern. Es ist ein langfristiges Wertwerkzeug für Systeme mit hohem Risiko.
JustinC

Die Idee ist, dass der Benutzer es nicht bemerken sollte, obwohl Unterkomponenten zufällig abstürzen. Wenn ein Tester meldet, dass einer der zufälligen Abstürze für ihn sichtbar war, würde dies bedeuten, dass der Absturz der Unterkomponente nicht abgefangen werden kann, was ein fileable Bug wäre.
Philipp

1
Was vorgeschlagen wird, ist in der Tat ein Live-Test des Umgangs mit schlechten Pfaden. Viele Bereitstellungen, und das Netflix-Beispiel ist ein typisches Beispiel, erfordern realistische Auslastungstests, die in vielen Fällen nur während der tatsächlichen Bereitstellung durchgeführt werden können. Programmatische Abstürze lassen sich mit einer offensichtlichen Protokollierung sehr leicht erkennen. Interessant ist der Kollateralschaden und die Auswirkung auf miteinander verbundene Systeme.
CTPENROSE

1
Sie können einen intelligenten Zufalls-Crasher (wie Chaos Monkey) implementieren, der Sie darüber informiert, wenn ein Programm zufällig abgestürzt ist. Auf diese Weise wissen Sie, wann Sie einen legitimen Absturz und wann es sich um einen Absturz beim Testen der Stabilität handelt.
Zain R

19

Das Einführen von Fehlern in Software oder Hardware zum Testen von Fehlertoleranzmechanismen wird als Fehlerinjektion bezeichnet .

Aus Wikipedia:

Die Technik der Fehlerinjektion stammt aus den 1970er-Jahren, als sie erstmals zur Auslösung von Fehlern auf Hardware-Ebene eingesetzt wurde. Diese Art der Fehlerinjektion wird als Hardware Implemented Fault Injection (HWIFI) bezeichnet und versucht, Hardwarefehler innerhalb eines Systems zu simulieren. Die ersten Versuche zur Hardwarefehlerinjektion umfassten lediglich das Kurzschließen von Verbindungen auf Leiterplatten und die Beobachtung der Auswirkungen auf das System (Überbrückungsfehler). Es wurde in erster Linie als Test für die Zuverlässigkeit des Hardwaresystems verwendet. Später wurde spezielle Hardware entwickelt, um diese Technik zu erweitern, beispielsweise Geräte, um bestimmte Bereiche einer Leiterplatte mit starker Strahlung zu beschießen. Es wurde bald festgestellt, dass Fehler durch Softwaretechniken hervorgerufen werden können und dass Aspekte dieser Technik zur Beurteilung von Softwaresystemen nützlich sein können.


+ Es passt als Second Level Stresstest. Nachdem die durchgeführten Stresstests [zu einem befriedigenden Grad] bestanden wurden, fügen Sie einige Zufälligkeiten ein, um sicherzustellen, dass unerwartete Umgebungsänderungen nicht katastrophal sind. Es kann wertvoll sein, wenn ein Ausfall ein hohes Risiko darstellt (Wahrscheinlichkeit oder Schwere der Konsequenz). Ich würde nicht bereitstellen, um zu leben, bis ich in einer Laborumgebung sehr sicher war, und dann nur inkrementell für die Teile, in denen ich am
sichersten war

9

Ja. Nein, vielleicht.

Periodische Kündigung ist ein zweischneidiges Schwert. Sie werden mit der einen oder der anderen Kante getroffen, und welches der beiden kleineren Übel von Ihrer Situation abhängt.

Ein Vorteil ist die Zuverlässigkeit: Wenn Sie das Programm zwingen, willkürlich (oder vorhersehbar) und ordnungsgemäß zu beenden, können Sie auf dieses Ereignis vorbereitet sein und damit umgehen. Sie können sicherstellen, dass der Prozess beendet wird, wenn keine anderen nützlichen Aufgaben ausgeführt werden. Dies garantiert auch, dass Bugs, die sich über die genehmigte Laufzeit hinaus manifestieren würden, ihre hässlichen Köpfe in der Produktion nicht aufrichten, was eine gute Sache ist. Apache HTTPD verfügt über eine Einstellung, mit der Sie festlegen können, wie viele Anforderungen ein untergeordneter Prozess (oder Thread in neueren Versionen) vor dem Beenden ausführen soll.

Der andere Vorteil ist auch die Zuverlässigkeit: Wenn Sie nicht zulassen, dass das Programm lange ausgeführt wird, werden Sie niemals Fehler finden, die sich im Laufe der Zeit manifestieren. Wenn Sie schließlich auf einen dieser Fehler stoßen, ist es viel wahrscheinlicher, dass das Programm eine falsche Antwort zurückgibt oder überhaupt keine zurückgibt. Schlimmer noch, wenn Sie viele Threads desselben Jobs ausführen, kann ein zeit- oder zählungsbedingter Fehler eine sehr große Anzahl von Aufgaben gleichzeitig betreffen und insgesamt zu einem 3-Uhr-Trip ins Büro führen.

In einer Umgebung, in der Sie viele der gleichen Threads ausführen (z. B. auf einem Webserver), besteht die praktische Lösung darin, einen gemischten Ansatz zu wählen, der zu einer akzeptablen Fehlerrate führt. Wenn Sie 100 Threads ausführen, bedeutet das Ausführen eines Short-to-Long-Verhältnisses von 99: 1, dass nur einer langfristige Fehler aufweist, während die anderen weiterhin das tun, was sie tun, ohne zu scheitern. Im Gegensatz dazu besteht bei einer Laufzeit von 100% ein viel höheres Risiko, dass alle Threads gleichzeitig ausfallen.

Wenn Sie einen einzelnen Thread haben, ist es wahrscheinlich besser, ihn einfach laufen zu lassen und fehlzuschlagen, da die Totzeit während eines Neustarts zu einer unerwünschten Latenz führen kann, wenn echte Arbeit zu erledigen ist, die erfolgreich abgeschlossen werden würde.

In beiden Fällen ist es wichtig, dass die Prozesse überwacht werden, damit sie sofort neu gestartet werden können. Es gibt auch kein Gesetz, das besagt, dass Ihre anfänglichen Entscheidungen darüber, wie lange ein Prozess ablaufen soll, in Stein gemeißelt werden müssen. Durch das Sammeln von Betriebsdaten können Sie Ihr System optimieren, um Ausfälle auf einem akzeptablen Niveau zu halten.

Ich würde davon abraten, eine zufällige Kündigung vorzunehmen, da dies die Ermittlung zeitbezogener Fehler erschwert. Chaos Monkey sorgt dafür, dass die Überwachungssoftware funktioniert, was ein etwas anderes Problem darstellt.


Wenn Sie den Prozess nach einem zufälligen Zeitintervall abbrechen, das bis ins Unendliche reicht, werden einige Prozesse für immer weiterleben. Daher denke ich nicht, dass das zufällige Beenden von Prozessen nicht mit dem Erkennen von Problemen mit langlebigen Prozessen vereinbar ist.
Joeri Sebrechts

9

Meinst du wirklich zufällig? Es klingt schrecklich, wenn sich Ihre Software zufällig selbst umbringt. Welchem ​​Punkt würde das dienen?

Ich vermute, Sie meinen damit wirklich, dass wir bei lang laufenden Threads / Prozessen realistisch sein sollten und akzeptieren sollten, dass je länger sie laufen, desto wahrscheinlicher ist, dass sie auf eine Art versteckten Fehler gestoßen sind und in einen nicht funktionierenden Zustand geraten sind Zustand. Aus rein pragmatischen Gründen sollte die Lebensdauer von Prozessen und Threads begrenzt werden.

Ich glaube, dass der Apache-Webserver in den späten 90ern so etwas benutzte. Sie hatten einen Pool von Worker-Prozessen (keine Threads) und jeder Worker-Prozess wurde nach einer festgelegten Lebensdauer beendet. Dies verhinderte, dass der Server von Arbeitsprozessen monopolisiert wurde, die in einem pathologischen Zustand stecken geblieben waren.

Ich habe einige Zeit nicht in der Gegend gearbeitet, daher weiß ich nicht, ob dies immer noch der Fall ist.


6
In IIS sind regelmäßige Neustarts in die Verwaltungsbenutzeroberfläche integriert und standardmäßig aktiviert. Es gibt auch Speicher- und CPU-begrenzende Trigger, aber der zeitbasierte hat mich immer als seltsam empfunden.
Mark Brackett

3
Bis zum heutigen Tag besteht die Lösung für Python-Speicherlecks in einem Neustart des Prozesses.
Xavi

3
Ich glaube nicht, dass das OP nach dem Beenden des Programms fragt, um es in einen ordnungsgemäß funktionierenden Zustand zu versetzen, sondern nach dem Beenden eines Programms, um die Fähigkeit des Systems zu testen, mit seinem Tod fertig zu werden, und um eventuelle nachfolgende Ausführungen des Programms zu bewältigen Überreste.
Mowwwalker

1
@MarkBrackett Leider scheint der periodische Neustart dem entgegengesetzten Zweck zu dienen, indem Programmierer über schlechten Code beleidigt werden. Wenn die Probleme, die durch fehlerhaften Code verursacht wurden, zu Problemen im Nacken führen, ist es weniger wahrscheinlich, dass wir fehlerhaften Code schreiben.
Anthony

+1. Zufall ist schlecht. Per Definition ist es so, dass Sie sein Verhalten nicht vorhersagen können. Selbst wenn Sie es dort ablegen, um das Programm von Zeit zu Zeit zu schließen, kann es sein, dass es einfach nicht ausgeführt wird, weil es zufällig ist, was den Zweck zunichte macht, es dort zu haben. Das Schließen der Prozesse in vorhersehbaren Momenten könnte für den Programmierer und auch für den Vermarkter, der versucht, dieses spezielle Feature zu verkaufen, einfacher sein. "Ja, das stimmt. Es wird in zufälligen Momenten geschlossen! Nein, es ist ein Feature! Hallo? Hallo ?!"
Neil

7

Das Problem, das ich sehe, ist, dass wenn ein solches Programm abstirbt, wir einfach sagen: "Oh, es ist nur eine weitere zufällige Beendigung - kein Grund zur Sorge." Aber was ist, wenn es ein echtes Problem gibt, das behoben werden muss? Es wird ignoriert.

Programme, die bereits "zufällig" erstellt wurden, scheitern daran, dass Entwickler Rätsel machen, Fehler in Produktionssystemen auftreten, Hardwarefehler auftreten usw. Wenn dies auftritt, möchten wir dies wissen, damit wir es beheben können. Das Design von Programmen für den Tod erhöht nur die Wahrscheinlichkeit eines Scheiterns und würde uns nur dazu zwingen, die Redundanz zu erhöhen, was Geld kostet.

Ich sehe nichts falsches daran, Prozesse in einer Testumgebung zufällig zu beenden, wenn ich ein redundantes System teste (dies sollte mehr passieren als es ist), aber nicht in einer Produktionsumgebung. Würden wir alle paar Tage ein paar Festplatten aus einem Live-Produktionssystem entfernen oder einen der Computer in einem Flugzeug deaktivieren, da es voller Passagiere ist? In einem Testszenario - gut. In einem Live-Produktionsszenario möchte ich lieber nicht.


Wenn Sie eine zufällige Beendigung implementieren würden, würden Sie mit Sicherheit eine Protokollnachricht "Jetzt kündige ich" ausgeben, mit der Sie beabsichtigte zufällige Kündigungen von Fehlern unterscheiden können. ;-) Auch ein gelegentlicher Neustart eines Prozesses würde keine weitere Redundanz erfordern, wie Sie es ohnehin hätten tun sollen.
Hans-Peter Störr

4

Das Hinzufügen eines zufälligen Beendigungscodes zur Anwendung sollte nicht erforderlich sein. Tester können Skripte schreiben, die die Prozesse der Anwendung zufällig beenden.

Beim Networking muss ein unzuverlässiges Netzwerk simuliert werden, um eine Protokollimplementierung zu testen. Dies wird nicht in das Protokoll integriert. Es kann auf Gerätetreiberebene oder mit externer Hardware simuliert werden.

Fügen Sie keinen Testcode hinzu. Führen Sie das Programm für Situationen aus, die extern erreicht werden können.

Wenn dies für die Produktion gedacht ist, kann ich nicht glauben, dass es ernst ist!

Erstens ist es keine ehrliche Umsetzung des Konzepts , wenn die Prozesse nicht abrupt beendet werden, sodass laufende Transaktionen und flüchtige Daten verloren gehen. Geplante, ordnungsgemäße Exits, auch wenn sie nach dem Zufallsprinzip ausgeführt werden, tragen nicht ausreichend dazu bei, die Architektur auf den Umgang mit echten, nicht ordnungsgemäßen Abstürzen vorzubereiten.

Wenn echte oder realistische Fehlfunktionen in die Anwendung eingebaut werden, können sie ebenso wie echte Fehlfunktionen zu einem wirtschaftlichen Schaden führen , und ein gezielter wirtschaftlicher Schaden ist im Grunde genommen per definitionem eine Straftat .

Möglicherweise können Sie Klauseln in der Lizenzvereinbarung umgehen, die die zivilrechtliche Haftung für Schäden aus dem Betrieb der Software aufheben. Wenn diese Schäden jedoch beabsichtigt sind, können Sie möglicherweise nicht auf die strafrechtliche Haftung verzichten.

Denken Sie nicht einmal an solche Stunts: Machen Sie es so zuverlässig wie möglich und fügen Sie gefälschte Fehlerszenarien nur in spezielle Builds oder Konfigurationen ein.


Dies sollte die akzeptierte Antwort IMO sein. Hier gilt SRP.
user408866

Leider meine ich nicht nur zum Testen. Ich werde die Frage erweitern, um zu erklären.
Jimbo

Wenn Sie es richtig machen, würden diese zufälligen (und nicht anmutigen!) Abstürze überhaupt keinen dauerhaften Schaden anrichten. Das ist der Punkt: Im Laufe der Zeit können Sie alle Randfälle aussortieren, in denen Schaden entsteht. Einige davon werden Sie auf Testmaschinen niemals sehen. Und wenn es mal zu einem echten Absturz kommt, haben Sie auch keine Probleme. Ich habe das nie ausprobiert, aber es scheint mir unter bestimmten Umständen sinnvoll zu sein. Natürlich muss dies ein offizielles Feature der Anwendung sein und keine Entwicklung.
Hans-Peter Störr

3

Möglicherweise möchten Sie im Kontext fehlertoleranter verteilter Systeme nach " proaktiver Wiederherstellung " und " Verjüngung " suchen , um willkürliche Fehler zu beheben (dh nicht nur abgestürzte Prozesse, sondern auch beschädigte Daten und potenziell böswilliges Verhalten). Es wurde viel nachgeforscht, wie oft und unter welchen Bedingungen ein Prozess (im abstrakten Sinne kann es sich tatsächlich um eine VM oder einen Host handeln) neu gestartet werden soll. Intuitiv können Sie die Vorteile des Ansatzes dahingehend verstehen, dass Sie es vorziehen, mit einem toten Prozess als mit einem Verräterprozess umzugehen ...


2

Das ist wirklich nichts anderes als testen. Wenn Sie eine jederzeit verfügbare Failover-Lösung (wie Netflix) entwerfen, sollten Sie sie testen. Ich weiß jedoch nicht, ob zufällige Exits, die über die gesamte Codebasis verteilt sind, eine geeignete Möglichkeit sind, dies zu testen. Wenn Sie nicht wirklich testen möchten, ob Ihr Design widerstandsfähig ist, um sich selbst in den Fuß zu schießen, ist es angemessener, es zu testen, indem Sie die Umgebung um den Code herum manipulieren und überprüfen, ob es sich ordnungsgemäß verhält.

Wenn Sie keine redundanten Systeme entwerfen, sollten Sie diese Funktion nicht hinzufügen, da Sie einige zufällige Exits hinzugefügt haben. Sie sollten nur die zufälligen Ausgänge entfernen, und dann werden Sie dieses Problem nicht haben. Möglicherweise fällt Ihre Umgebung immer noch aus. Zu diesem Zeitpunkt werden Sie den Code entweder als nicht unterstützt / nicht repariert kennzeichnen oder ihn gegen diesen Fehler absichern und einen Test hinzufügen. Tun Sie das oft genug, und Sie werden feststellen , dass Sie tatsächlich sind ein redundantes System entwerfen - siehe Szenario # 1.

Irgendwann stellen Sie möglicherweise fest, dass Sie nicht mehr sicher sind, welche Fehler behandelt werden oder nicht. Jetzt können Sie den Teppich nach dem Zufallsprinzip herausziehen, um die Fehlerstellen zu erkennen.

Das einzig interessante am Netflix-Beispiel ist, dass diese Tests in der Produktion durchgeführt werden. Das ist in gewisser Weise sinnvoll - einige Bugs sind in Wirklichkeit reine Produktionssachen, die in einer isolierten Umgebung nur sehr schwer oder gar nicht zu simulieren sind. Ich vermute, dass Netflix eine lange Zeit in Testumgebungen verbracht hat, bevor sie dies in der Produktion tun konnten. Und alles, was sie tun, ist zu versuchen, Abstürze während der Geschäftszeiten zu verursachen, was für ihren Markt einen gewissen Sinn ergibt, für viele andere aber nicht.


2

Der Begriff, den Sie suchen, wurde kürzlich von Nassim Nicholas Taleb geprägt: Antifragility. Sein Buch Antifragile ist auf jeden Fall zu empfehlen. IT wird kaum erwähnt, aber die unausgesprochenen, offensichtlichen Parallelen sind am inspirierendsten. Seine Idee ist es, die Skala von fragilem <-> robustem <-> robustem <-> Antifragilem zu erweitern. Fragile Pausen mit zufälligen Ereignissen, robustes Management mit zufälligen Ereignissen und anti-fragile Gewinne mit zufälligen Ereignissen.


1

Es hängt davon ab, ob. Ich habe bemerkt, dass Programmierer dazu neigen, die Techniken, die auf ihre spezifische Domäne zutreffen, zu übermäßig zu verallgemeinern, wobei sie alle anderen ignorieren. Zum Beispiel kann es sinnvoll sein, ein Programm auf Kosten der Behebung aller Fehler freizugeben ... es sei denn, Sie programmieren Fluglotsen, Kernreaktoren usw. "Nicht optimieren - die Kosten für Programmierer sind höher als die Kosten für die Programmausführung" sind nicht erforderlich Gültig für HPC, da dort ein relativ einfaches Programm monatelang Cluster belegen kann usw. (oder sogar ein beliebtes Programm, das von einer großen Anzahl von Benutzern verwendet wird). Selbst wenn die Firma X Y aus einem sehr guten Grund tut, müssen Sie nicht unbedingt ihren Schritten folgen, da Ihre Situation möglicherweise anders ist.

Normalerweise sind die Fehlerbehandlungsroutinen der schlechteste Teil des Codes - obwohl es einfach zu sein scheint, ist es schwierig zu simulieren, dass nicht genügend Arbeitsspeicher vorhanden ist oder dass eine wichtige Datei nicht vorhanden ist. Aus diesem Grund lese ich Texte, in denen vorgeschlagen wird, dass der Unix-Kernel einige Systemaufrufe nach dem Zufallsprinzip abbricht. Es würde jedoch das Schreiben einfacher Programme erschweren (wenn ich 3 C ++ - Bibliotheken zusammenstecken müsste, um ein Programm mit 2 Dateien auszuführen, wenn ich mich nicht um die Fehlerbehandlung kümmern möchte). Auch mit Ausnahme von GC müssen Sie sicherstellen, dass Sie den konsistenten Zustand hinter sich gelassen haben (stellen Sie sich eine Ausnahme vor, während Sie einen Knoten zu einer verknüpften Liste hinzufügen).

Je mehr verteilte Dienste Sie haben, desto häufiger stellt sich die Frage nach dem "Wie häufig" und dem "Wenn" oder "Wann". In Rechenzentren gehört das Ersetzen von Festplatten in RAIDs meines Wissens zur Routine - keine unerwarteten Ausfälle. Wenn Sie in großem Maßstab arbeiten, müssen Sie dies berücksichtigen, denn selbst wenn die Wahrscheinlichkeit eines Ausfalls einer Komponente gering ist, besteht die Möglichkeit, dass etwas ausfällt.

Ich weiß nicht genau, was Sie tun, aber um zu wissen, ob es sich lohnt, müssen Sie überlegen, ob Sie Fehler berücksichtigen müssen (wenn Sie sie ignorieren) oder ob die Analyse zu kostspielig ist (wenn Sie Fehler in Kauf nehmen) Entwicklungszeit berücksichtigen).


"Programmierer neigen dazu, die Techniken, die auf ihre spezifische Domäne zutreffen, zu stark zu verallgemeinern." Ich möchte dieses Zitat einrahmen und an die Wand hängen. Es ist sooooo wahr und nicht nur von Software, sondern vom Leben im Allgemeinen.
Mark E. Haase

1

Der IIS-Server verfügt über eine konfigurierbare Funktion, mit der Arbeitsprozesse automatisch wiederverwendet werden, nachdem sie eine bestimmte Menge an Arbeitsspeicher verbraucht oder eine bestimmte Anzahl von Anforderungen bearbeitet haben oder eine bestimmte Zeit lang am Leben waren. ( http://msdn.microsoft.com/en-us/library/ms525803(v=vs.90).aspx ) und ( http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/ 1652e79e-21f9-4e89-bc4b-c13f894a0cfe.mspx? Mfr = true )

Wenn ein CONTAINER wie IIS dies tut, ist es sinnvoll, den Server vor unerwünschten Prozessen zu schützen. Ich würde es jedoch vorziehen, dies deaktiviert zu lassen, da es keinen Sinn ergibt, wenn Sie Ihren Code ausreichend getestet haben.

Wir arbeiten bereits an unzuverlässigen Schichten (Hardware, Netzwerk), daher würde ich niemals Code schreiben, der seine Threads oder Prozesse absichtlich zufällig abbricht. Zufälliges Töten ist auch aus wirtschaftlicher Sicht eine schlechte Idee - niemand würde meine API verwenden, wenn er annehmen würde, dass ich sie so programmiert habe, dass sie zufällig abstürzt. Wenn ich eine API verbrauchen oder ein System mit zufällig abstürzenden Threads verwenden würde, müsste ich eine Menge Geld ausgeben, um einen Überwachungsmechanismus zu schaffen, der robust genug ist, damit ich nachts ruhig schlafen kann.

Stattdessen, wenn ich ein System oder eine API entwickeln würde, würde ich Skripte schreiben oder ein Geschirr verwenden, das dies nur tun würde, um die Belastbarkeit des Systems zu testen. Und ich würde einen solchen Testlauf für alle Builds durchführen, um fehlerhafte Builds zu identifizieren. Obwohl dies ein notwendiger Test wäre, könnte es niemals ein "ausreichender" Test sein.


1

Es gibt eine Literatur zu dieser Idee, die sich Crash-Only-Software (auch Recovery Oriented Computing) nennt, und Sie können mit diesem Usenix-Papier von Candea & Fox aus dem Jahr 2003 beginnen Halten Sie Ihre Programme immer an, indem Sie sie beenden, sodass Sie einen einzigen Kill-Schalter als Abschaltknopf und einen einzigen, gut trainierten Startpfad für die Wiederherstellung haben.

Ich bin mir nicht sicher, wie gut die Idee angekommen ist, aber einige der spezifischen Techniken bleiben nützlich. Sie können beispielsweise nicht darauf vertrauen, dass sich Ihre Software bei Aufforderung selbst herunterfährt, und verwenden dazu spezielle Überwachungsprogramme (z. B. Supervisord usw.). Überlegen Sie außerdem sorgfältig, welcher Programmstatus von wesentlicher Bedeutung ist, und stellen Sie sicher, dass er zu geeigneten Zeiten in einem Datenspeicher gespeichert wird um die Wiederherstellung zu ermöglichen (zB eine SQL-Datenbank).


2
Links veralten. Ihre Antwort wäre besser, wenn Sie in Ihrer Antwort die wichtigsten Punkte der Crash-Only-Software zusammenfassen würden.

1

Wirklich zufällig, nein. Es ist jedoch wahrscheinlich eine gute Idee, Prozesse / Threads mit langer Laufzeit in einem bestimmten Intervall zu beenden / neu zu starten, oder nachdem sie für eine bestimmte (aber von bestimmten Kriterien abhängige) Dauer inaktiv waren oder eine bestimmte Art von Task ausgeführt haben. Langfristig laufende Prozesse bauen unweigerlich einen Zustand auf, der veraltete Dinge einschließt. Vermutlich bleibt der Speicher erhalten und verhindert, dass Auslagerungsspeicher freigegeben werden, der beim Beenden bereinigt wird (oder werden sollte), wodurch die allgemeine Systemstabilität verbessert wird.


1

Dies hängt von der Art der Anwendung ab, die Sie entwerfen.

Zufällige Abstürze sind eine hervorragende Möglichkeit, die Robustheit verteilter (vernetzter) Systeme zu testen und zu verbessern.

Im Netflix-Beispiel, wenn Ihr Programm von Remotediensten abhängt, die aus verschiedenen Gründen, die Sie nicht kontrollieren können, ausfallen (Festplatte geht kaputt, Stromausfall, Meteorabstürze im Rechenzentrum usw.). Ihr Dienst muss trotzdem weiterlaufen.

Wie machst du das? Hinzufügen von Redundanz und Skalierung ist eine häufige Lösung.

Wenn zum Beispiel eine Maus durch das Stromkabel Ihres Servers kaut, sollte Ihr Dienst eine Lösung haben, um weiterlaufen zu können. Es kann zum Beispiel redundante Backup-Server behalten, die es stattdessen verwendet.

Wenn es sich bei Ihrem Programm jedoch um eine Einzelprozessanwendung handelt, die nicht in einem Netzwerk ausgeführt wird, kann das Beenden des Programms nichts testen, da es keine Möglichkeit gibt, sich davon zu erholen.

Hier ist ein zusätzlicher Kommentar zum Chaos Monkeys-Konzept: http://www.codinghorror.com/blog/2011/04/working-with-the-chaos-monkey.html


1

Es ist möglich, dass aufgrund der kosmischen Strahlung ein zufälliger Bitwechsel auftritt . Dieses Problem wurde erkannt und verschiedene Techniken wurden entwickelt, um das Auftreten von Bitflips zu verhindern.

Es ist jedoch nicht möglich, das Problem zu 100% zu beheben, und eine Speicherbeschädigung kann immer noch Probleme verursachen, und diese Probleme treten immer noch auf ( mit sehr geringer Wahrscheinlichkeit ).

Nun zur Beantwortung Ihrer Frage. Ob Sie ein sehr robustes System entwerfen müssen oder nicht, hängt davon ab, was Sie tun. Wenn Sie ein Raumschiff erstellen müssen, machen Sie es besser super robust, und dann müssen Sie jedes mögliche Problem berücksichtigen.

Wenn Sie eine normale Desktop-Anwendung entwerfen müssen, sollten Sie zufällige Abstürze als Fehler in Ihrem Code betrachten.


0

Das scheint keine absurde Idee zu sein.

Android OS beendet und startet Benutzer-Apps / -Dienste ständig nach dem Zufallsprinzip. Nach meiner Erfahrung hat es mir auf jeden Fall geholfen, tiefer über Fehlerbedingungen nachzudenken und robustere Architekturen zu entwerfen.


4
Die Aktionen von Android sind nicht zufällig, aber Aktivitäten müssen in der Lage sein, den Status zu speichern, wenn sie dazu aufgefordert werden. Es gibt einen subtilen, aber wichtigen Unterschied.
Blrfl

Von dem, was ich gelesen habe , gibt es keine Garantie , dass onDestroy, onPause, onSaveInstanceStateusw ... jemals auf einer Tätigkeit oder Dienstleistung aufgerufen werden. Auf App-Ebene gibt es nicht einmal einen onDestoryRückruf. Also ja, es gibt einige Haken für elegantes Herunterfahren, aber Sie müssen immer noch auf zufällige Ausgänge vorbereitet sein.
Xavi

Sie werden garantiert angerufen, onPause()bevor eine Aktivität beendet wird. Nach Honeycomb ist dieses Plus garantiert onStop(). Android-Apps sind nur Sammlungen von Aktivitäten, die in Zusammenhang stehen, und es gibt kein Konzept auf App-Ebene, was den Ausführungslebenszyklus betrifft.
Blrfl

Ahh gut zu wissen.
Xavi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.