En un mot, devrions-nous inclure la mort dans nos programmes, processus et threads à un niveau bas, pour le bien du système global?
Les échecs se produisent. Les processus meurent. Nous planifions en cas de catastrophe et en récupérons parfois. Mais nous concevons et mettons rarement en œuvre un programme de mort imprévisible. Nous espérons que les temps de disponibilité de nos services durent aussi longtemps que nous veillons à les maintenir en activité.
Le macro-exemple de ce concept est Chaos Monkey de Netflix , qui termine de manière aléatoire les instances AWS dans certains scénarios. Ils affirment que cela les a aidés à découvrir des problèmes et à créer davantage de systèmes redondants.
Ce dont je parle est le niveau inférieur. L'idée est que les processus de longue durée se terminent de manière aléatoire. Cela devrait forcer la redondance dans la conception et finalement produire des systèmes plus résilients.
Ce concept a-t-il déjà un nom? Est-il déjà utilisé dans l'industrie?
MODIFIER
Sur la base des commentaires et des réponses, j'ai bien peur que ma question ne soit pas claire. Pour plus de clarté:
- oui, je veux dire au hasard,
- oui, je parle de production et
- non, pas seulement pour les tests.
Pour expliquer, j'aimerais faire une analogie avec les organismes multicellulaires.
Dans la nature, les organismes sont constitués de nombreuses cellules. Les cellules se bifurquent pour créer une redondance et finissent par mourir. Mais il devrait toujours y avoir suffisamment de cellules du bon type pour que l'organisme puisse fonctionner. Ce système hautement redondant facilite également la guérison des blessures. Les cellules meurent pour que l'organisme vive.
L’incorporation de la mort aléatoire dans un programme obligerait le système élargi à adopter des stratégies de redondance pour rester viable. Ces mêmes stratégies aideraient-elles le système à rester stable face à d'autres types d'échecs imprévisibles?
Et, si quelqu'un a essayé, comment s'appelle-t-il? J'aimerais en savoir plus à ce sujet s'il existe déjà.
Réponses:
Non.
Nous devons concevoir une gestion appropriée des mauvais chemins et concevoir des scénarios de test (et d’autres améliorations de processus) pour valider que les programmes gèrent bien ces conditions exceptionnelles. Des choses comme Chaos Monkey peuvent en faire partie, mais dès que vous faites "doit tomber en panne de manière aléatoire", une exigence de vrais crashs aléatoires deviennent des choses que les testeurs ne peuvent pas déclarer comme des bogues.
la source
Le processus d’introduction de défauts dans les logiciels ou dans le matériel afin de tester les mécanismes de tolérance aux pannes est appelé injection de fautes .
De Wikipedia:
la source
Oui. Non peut-être.
La résiliation périodique est une arme à deux tranchants. Vous allez être frappé d'un côté ou de l'autre, et le moindre des deux maux dépend de votre situation.
La fiabilité est un avantage: si vous forcez le programme à se terminer de manière aléatoire (ou prévisible) et de manière ordonnée, vous pouvez être préparé pour cet événement et y faire face. Vous pouvez garantir que le processus se terminera s'il n'est pas occupé à faire quelque chose d'utile. Cela garantit également que les bogues qui se manifesteraient au-delà de la durée autorisée ne se dresseraient pas la tête la première fois en production, ce qui est une bonne chose. Apache HTTPD a un paramètre qui vous permettra de définir le nombre de requêtes qu'un processus enfant (ou un thread dans les versions plus récentes) servira avant la fin.
L’autre avantage est également la fiabilité: si vous ne laissez pas le programme s’exécuter longtemps, vous ne trouverez jamais de bogues qui se manifesteront au fil du temps. Lorsque vous rencontrez finalement l'un de ces bogues, il est beaucoup plus probable que le programme renvoie une réponse incorrecte ou ne la renvoie pas du tout. Pire, si vous exécutez plusieurs threads du même travail, un bogue induit par le temps ou le comptage peut affecter un très grand nombre de tâches en même temps et entraîner un trajet de trois heures au bureau.
Dans les cas où vous exécutez plusieurs threads identiques (sur un serveur Web, par exemple), la solution pratique consiste à adopter une approche mixte qui aboutit à un taux de défaillance acceptable. Si vous exécutez 100 threads, un ratio court / long de 99: 1 signifie qu'un seul d'entre eux présentera des bogues à long terme, tandis que les autres continueront à faire ce qu'ils font sans échouer. Comparez cela à une longueur de 100%, où vous courez un risque beaucoup plus grand que tous les threads échouent en même temps.
Lorsque vous avez un seul thread, il est probablement préférable de le laisser fonctionner sans succès, car le temps mort lors d'un redémarrage peut entraîner une latence non désirée lorsqu'il existe un réel travail à accomplir pour réussir ce travail.
Dans les deux cas, il est important de superviser les processus pour pouvoir les redémarrer immédiatement. En outre, aucune loi ne dit que vos décisions initiales sur la durée d'un processus doivent être gravées dans le marbre. La collecte de données opérationnelles vous aidera à adapter votre système afin de limiter les défaillances à un niveau acceptable.
Je recommanderais de ne pas faire de résiliation aléatoire, car cela rend plus difficile la détection des bugs liés au temps. Chaos Monkey le fait pour s'assurer que le logiciel de supervision fonctionne, ce qui pose un problème légèrement différent.
la source
Voulez-vous vraiment dire au hasard? Avoir votre logiciel se tuer au hasard semble être une idée terrible. Quel point cela servirait-il?
Je suppose que ce que vous voulez vraiment dire, c'est que nous devrions être réalistes à propos des threads / processus longs et accepter le fait que plus ils fonctionnent longtemps, plus ils sont susceptibles d'avoir rencontré une sorte de bogue cachée et d'être entrés dans un processus non fonctionnel. Etat. Ainsi, en tant que mesure purement pragmatique, la durée de vie des processus et des threads doit être limitée.
Je pense qu'à la fin des années 90, le serveur Web Apache utilisait quelque chose comme ceci. Ils avaient un pool de processus de travail (pas de threads) et chaque processus de travail serait tué après une durée de vie fixe. Cela évitait que le serveur ne soit monopolisé par des processus de travail bloqués dans un état pathologique.
Je n'ai pas travaillé dans la région depuis un certain temps, donc je ne sais pas si c'est toujours le cas.
la source
Le problème que je vois est que si un tel programme meurt, nous dirons simplement "Oh, c'est juste une autre terminaison aléatoire - rien à craindre". Mais que se passe-t-il s'il existe un problème réel qui doit être résolu? Il sera ignoré.
Les programmes échouent déjà "de manière aléatoire" à cause des développeurs créant des mystaykes, des bogues dans les systèmes de production, des pannes matérielles, etc. Lorsque cela se produit, nous voulons le savoir afin de le réparer. Intégrer la mort dans les programmes n'augmente que la probabilité d'échec et nous obligerait à augmenter les licenciements, ce qui coûte de l'argent.
Je ne vois aucun mal à tuer des processus de manière aléatoire dans un environnement de test lors du test d'un système redondant (cela devrait se produire davantage), mais pas dans un environnement de production. Est-ce que nous retirerions quelques disques durs d'un système de production live tous les quelques jours, ou désactiverions l'un des ordinateurs d'un avion en vol plein de passagers? Dans un scénario de test - bien. Dans un scénario de production en direct, je préférerais ne pas.
la source
L'ajout de code de sortie aléatoire à l'application ne devrait pas être nécessaire. Les testeurs peuvent écrire des scripts qui tuent de manière aléatoire les processus de l'application.
En réseau, il est nécessaire de simuler un réseau peu fiable pour tester une implémentation de protocole. Cela ne fait pas partie du protocole. il peut être simulé au niveau du pilote de périphérique ou avec du matériel externe.
N'ajoutez pas de code de test dans le programme pour les situations pouvant être réalisées en externe.
Si cela est destiné à la production, je ne peux pas croire que c'est sérieux!
Premièrement, à moins que les processus ne se terminent brusquement , entraînant ainsi la perte de transactions en cours et de données volatiles, il ne s'agit pas d'une mise en œuvre honnête du concept. Les sorties planifiées et harmonieuses, même si elles ont été programmées au hasard, ne permettent pas de préparer correctement l'architecture à la gestion des crashs réels, qui ne le sont pas.
Si des dysfonctionnements réels ou réalistes sont intégrés à l'application, ils pourraient entraîner un préjudice économique, tout comme de réels dysfonctionnements, et un préjudice économique intentionnel est fondamentalement un acte criminel presque par définition.
Vous pouvez peut-être vous échapper avec des clauses dans le contrat de licence qui renoncent à la responsabilité civile de tout dommage résultant de l'utilisation du logiciel, mais si ces dommages sont inhérents à votre conception, vous ne pourrez peut-être pas renoncer à une responsabilité pénale.
Ne pensez même pas à des cascades comme celui-ci: faites-le fonctionner de manière aussi fiable que possible et ne créez de faux scénarios d'échec que dans des versions ou des configurations spéciales.
la source
Vous voudrez peut-être rechercher « récupération proactive » et « régénération » dans le contexte des systèmes répartis tolérants aux pannes, afin de traiter les erreurs arbitraires (non seulement les processus bloqués, mais également les données corrompues et les comportements potentiellement malveillants). Il y a eu beaucoup de recherches sur la fréquence et les conditions dans lesquelles un processus (dans un sens abstrait, peut en fait être un ordinateur virtuel ou un hôte) doit être redémarré. Intuitivement, vous pouvez comprendre les avantages de l'approche comme préférant traiter avec un processus mort que avec un processus de traître ...
la source
Ce n'est vraiment pas différent que de tester. Si vous concevez une solution de basculement toujours disponible (telle que Netflix), alors oui, vous devez la tester. Je ne sais pas si des sorties aléatoires parsèment la base de code est un moyen approprié de tester cela, cependant. À moins que vous ne vouliez vraiment vérifier que votre conception est résistante, il semblerait plus approprié de la tester en manipulant l' environnement autour du code et en vérifiant qu'il se comporte correctement.
Si vous ne concevez pas de systèmes redondants, alors non - vous ne devriez pas ajouter cette fonctionnalité car vous avez ajouté des exits aléatoires. Vous devriez simplement supprimer les sorties aléatoires, et vous n'aurez alors pas ce problème. Votre environnement peut toujours échouer sur vous. À ce stade, vous pouvez soit le qualifier de non pris en charge / ne corrige pas, soit renforcer votre code contre cet échec et ajouter un test. Faites cela assez souvent, et vous vous rendrez compte que vous avez réellement êtes conception d' un système redondant - voir le scénario n ° 1.
À un moment donné, vous pouvez déterminer que vous n'êtes plus sûr des défaillances traitées ou non. Vous pouvez maintenant commencer à tirer au hasard sur le tapis pour détecter les points de défaillance.
La seule chose intéressante à propos de l'exemple Netflix est qu'ils exécutent ces tests en production. Cela a un certain sens: certains bogues ne produisent en réalité que des choses très difficiles voire impossibles à simuler dans un environnement isolé. Je soupçonne que Netflix a passé beaucoup de temps dans des environnements de test avant d’être suffisamment à l’aise pour le faire en production. Et tout ce qu'ils font, c'est d'essayer de provoquer des accidents pendant les heures de bureau, ce qui est tout à fait logique pour leur marché, mais pas pour beaucoup d'autres.
la source
Le terme que vous recherchez a été récemment inventé par Nassim Nicholas Taleb: Antifragilité. Son livre Antifragile est définitivement recommandé. Il mentionne à peine l'informatique, mais les parallèles évidents et non prononcés sont des plus inspirants. Son idée est d’étendre l’échelle de <-> robuste à fragile <-> robuste <-> antifragile. Pauses fragiles avec événements aléatoires, gestion robuste avec événements aléatoires et gains anti-fragiles avec événements aléatoires.
la source
Ça dépend. J'ai remarqué que les programmeurs ont tendance à trop généraliser les techniques qui s'appliquent à leur domaine spécifique en ignorant toutes les autres. Par exemple, obtenir un programme publié au prix de la résolution de tous les bugs peut être une bonne chose ... sauf si vous programmez un contrôleur d'aéronef, un réacteur nucléaire, etc. "N'optimisez pas - le coût du programmeur est supérieur au coût du programme en cours" n'est pas nécessaire. valide pour HPC car un programme relativement simple peut occuper un cluster pendant des mois, etc. (ou même un programme populaire utilisé par un grand nombre d’utilisateurs). Donc, même si la société X fait Y pour de très bonnes raisons, vous n’avez pas nécessairement besoin de suivre leurs traces, car votre situation pourrait être différente.
Habituellement, les routines de traitement des erreurs sont la partie du code la plus testée - bien que cela paraisse simple, il est difficile de simuler le manque de mémoire ou l'absence de fichiers importants. C'est pour cette raison que j'ai lu des textes proposant que le noyau Unix échoue de manière aléatoire dans certains appels système. Cependant, il serait plus difficile d’écrire un programme simple (si j’ai besoin de connecter 3 bibliothèques C ++ ensemble pour exécuter un programme sur 2 fichiers une fois que je ne veux plus me soucier de la gestion des erreurs). Même avec des exceptions, vous devez vous assurer que vous conservez un état cohérent (imaginez une exception au milieu de l’ajout du noeud à la liste chaînée).
Plus vous avez de services distribués, plus le nombre d'échecs est important, plus la question de "quelle fréquence" est-elle alors "si" ou "quand". Dans les centres de données, le remplacement des disques dans les RAID fait partie des opérations de routine de ce que je sais - pas des échecs inattendus. Si vous opérez à grande échelle, vous devez en tenir compte, car même si la probabilité de défaillance d’un composant est faible, il est probable que quelque chose échoue.
Je ne sais pas ce que vous faites exactement, mais pour savoir si cela en vaut la peine, vous devez penser si vous devez prendre en compte l'échec (en l'ignorant des coûts) ou trop coûteux en analyse (en prenant des erreurs compte du temps de développement des coûts).
la source
Le serveur IIS dispose d'une fonctionnalité configurable qui recycle automatiquement les processus de travail après avoir utilisé une certaine quantité de mémoire, après avoir traité un certain nombre de demandes ou après avoir été en vie pendant une période spécifiée. ( http://msdn.microsoft.com/en-us/library/ms525803(v=vs.90).aspx ) et ( http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/ 1652e79e-21f9-4e89-bc4b-c13f894a0cfe.mspx? Mfr = true )
Lorsqu'un conteneur comme IIS le fait, il est logique de protéger le serveur contre les processus malveillants. Cependant, je préférerais que cette option soit désactivée, car cela n’a aucun sens si vous avez suffisamment testé votre code.
Nous travaillons déjà sur des couches non fiables (matériel, réseau) et je n’écrirais donc jamais de code qui tue ses processus ou processus de manière aléatoire. Tuer au hasard est également une mauvaise idée d'un point de vue économique - personne n'utiliserait mon API s'il pensait que je l'avais programmé pour un crash aléatoire. Enfin, si je devais utiliser une API ou utiliser un système avec des threads en panne aléatoires, je devrais dépenser beaucoup d’argent pour créer un mécanisme de surveillance suffisamment robuste pour pouvoir dormir paisiblement la nuit.
Si je développais un système ou une API, j’écrirais des scripts ou utiliserais un harnais qui le ferait uniquement pour mettre à l’épreuve la résilience du système. Et je voudrais faire un tel test sur toutes les versions pour identifier les mauvaises versions. Cependant, bien que ce soit un test nécessaire, il ne pourrait jamais être un test "suffisant".
la source
Il existe une littérature liée à cette idée, son logiciel appelé Crash-Only (également Recovery Oriented Computing) et vous pouvez commencer avec cet article usenix de Candea & Fox à partir de 2003. Plutôt que de tuer au hasard, l'auteur affirme que vous pouvez améliorer la fiabilité du système en: Arrêtez jamais vos programmes en les supprimant. Vous devez donc disposer d’un commutateur unique en tant que bouton d’arrêt et d’un chemin de démarrage unique pour la récupération.
Bien que je ne sois pas sûr de l’idée retenue, certaines techniques restent utiles. Par exemple, ne pas faire confiance à votre logiciel pour pouvoir s’éteindre automatiquement à la demande et utiliser des programmes de supervision spécialisés (par exemple, supervisord, etc.), et réfléchir soigneusement à l’état essentiel du programme et s’assurer qu’il est enregistré à des moments appropriés dans un magasin de données conçu pour permettre la récupération (par exemple, une base de données SQL).
la source
Vraiment au hasard, non. Mais il est probablement judicieux que les processus / threads de longue durée quittent / redémarrent à un intervalle donné, ou après avoir été inactifs pendant une durée donnée (mais en fonction de certains critères), ou après avoir exécuté un type de tâche particulier. Les processus longs qui s'accumulent impliquent inévitablement des objets obsolètes, ce qui peut permettre de conserver la mémoire, empêchant ainsi la libération de l'espace d'échange. Tous ces éléments sont nettoyés (ou doivent être nettoyés) lorsqu'ils sortent, améliorant ainsi la stabilité générale du système.
la source
Cela dépend du type d'application que vous concevez.
Les accidents aléatoires sont un excellent moyen de tester et d'améliorer la robustesse des systèmes distribués (en réseau).
Dans l'exemple Netflix, lorsque votre programme dépend de services distants pouvant échouer pour diverses raisons que vous ne maîtrisez pas (disque dur défectueux, panne d'alimentation, météore plante dans le centre de données, etc.). Cependant, votre service doit continuer à fonctionner.
Comment tu fais ça? Ajoutez de la redondance et la mise à l'échelle est une solution courante.
Par exemple, si une souris coupe le câble d'alimentation de votre serveur, votre service devrait disposer d'une solution pour continuer à fonctionner. Il peut par exemple conserver des serveurs de sauvegarde redondants qu'il commencera à utiliser.
Cependant, si votre programme est une application à processus unique qui ne fonctionne pas sur un réseau, le fait de se tuer lui-même ne testera rien car il n'y a aucun moyen de récupérer à partir de cela.
Voici quelques commentaires supplémentaires sur le concept de Chaos Monkeys http://www.codinghorror.com/blog/2011/04/working-with-the-chaos-monkey.html
la source
Il est possible qu'un basculement aléatoire se produise en raison d' un rayonnement cosmique . Ce problème a été reconnu et diverses techniques ont été développées pour empêcher le retournement des bits.
Cependant, il n'est pas possible de le réparer à 100% et la corruption de mémoire peut toujours causer des problèmes, et ces problèmes persistent ( avec une probabilité très faible ).
Maintenant, répondez à votre question. Que vous ayez ou non besoin de concevoir un système très robuste, cela dépend de ce que vous faites. Si vous avez besoin de créer un vaisseau spatial, vous feriez mieux de le rendre super robuste, et vous devrez alors prendre en compte tous les problèmes possibles.
Si vous devez concevoir une application de bureau normale, vous devez considérer les plantages aléatoires comme des bogues dans votre code.
la source
Cela ne semble pas si absurde d'une idée.
Le système d'exploitation Android tue et redémarre de façon aléatoire les applications et les services des utilisateurs. D'après mon expérience, cela m'a certainement aidé à approfondir ma réflexion sur les conditions d'erreur et à concevoir des architectures plus robustes.
la source
onDestroy
,onPause
,onSaveInstanceState
, etc ... sera jamais appelé une activité ou service. Au niveau de l'application, il n'y a même pas deonDestory
rappel. Alors oui, il y a des crochets pour les arrêts progressifs, mais vous devez tout de même être préparé à des sorties aléatoires.onPause()
avant qu'une activité ne soit tuée. Après Honeycomb, vous avez la garantie de bénéficier de plusonStop()
. Les applications Android ne sont que des ensembles d'activités liées entre elles et il n'existe aucun concept au niveau de l'application pour ce qui est du cycle de vie de l'exécution.