2010-06-16 32 views
5

J'ai récemment couru dans un bug où une application Erlang ensemble est mort, ce qui donne un message de journal qui ressemblait à ceci:automatiquement le redémarrage des applications Erlang

=INFO REPORT==== 11-Jun-2010::11:07:25 === 
    application: myapp 
    exited: shutdown 
    type: temporary 

Je ne sais pas ce qui a déclenché cet arrêt, mais le vrai problème que je est qu'il ne s'est pas redémarré. Au lieu de cela, la VM Erlang, maintenant vide, restait là à ne rien faire. Maintenant, d'après les recherches que j'ai faites, il semble qu'il existe d'autres «types de démarrage» que vous pouvez donner à une application: «transitoire» et «permanente».

Si je commence un superviseur au sein une application, je peux dire pour faire un processus particulier transitoire ou permanente, et il redémarre automatiquement pour moi. Cependant, selon la documentation, si je fais une application transitoire ou permanente, elle ne la redémarre pas lorsqu'elle meurt, mais elle tue plutôt toutes les autres applications. Ce que je veux vraiment faire est en quelque sorte de dire à la machine virtuelle Erlang qu'une application particulière doit toujours être en cours d'exécution, et si elle tombe en panne, redémarrez-la. Est-ce possible?

(Je ne parle pas de mettre en place un superviseur en plus de mon application, car alors c'est un piège 22: que se passe-t-il si mon superviseur se bloque, je cherche une sorte d'API ou de paramètre avoir Erlang moniteur et redémarrer mon application pour moi.)

Merci!

Répondre

5

Vous devriez pouvoir résoudre ce problème dans le superviseur de niveau supérieur: définissez la stratégie de redémarrage pour autoriser un million de redémarrages toutes les secondes et l'application ne devrait jamais tomber en panne. Quelque chose comme:

init(_Args) -> 
    {ok, {{one_for_one, 1000000, 1}, 
      [{ch3, {ch3, start_link, []}, 
      permanent, brutal_kill, worker, [ch3]}]}}.

(. Exemple adapté de la OTP Design Principles User Guide)

+0

Très bien, merci beaucoup pour votre réponse. Je vois maintenant que la raison de sa mort était en effet parce que la limite de redémarrage maximum a été atteinte. Cependant, je ne veux pas forcément désactiver cela, car si la boucle redémarre, nous devrons peut-être redémarrer l'application entière. Est-il possible de le faire redémarrer si la limite AllowedRestarts/MaxSeconds est atteinte, au lieu de fermer l'application? – Nick

+1

Dans le cas que vous décrivez, vous ajouteriez un superviseur à votre superviseur. Le comportement qu'utilise OTP est celui lorsqu'un signal de sortie est envoyé au processus qui fait l'appel de début à l'application (c.-à-d.quand le superviseur de niveau supérieur meurt) il suppose que l'application a échoué pour corriger l'erreur et il fermera l'application et possible le noeud selon la config. Je suppose que le point est que vos applications ne devraient pas tomber en panne, et si elles le font l'erreur est assez sérieuse pour être seulement résolue par un redémarrage de noeud. – Lukas

+0

Lien est 404 - quelqu'un at-il une mise à jour ....? – jisaacstone

4

Vous pouvez utiliser heart pour redémarrer la machine virtuelle entier si elle descend, puis utilisez un type d'application permanente pour vous assurer que la machine virtuelle sort lorsque votre application se termine. En fin de compte, vous avez besoin de quelque chose au dessus de votre application, que ce soit un processus de superviseur, la machine virtuelle erlang ou un script shell que vous avez écrit - ce sera toujours un problème si cela échoue également.

+0

D'accord, merci. Ce genre de solution fonctionnera bien pour moi dans ce cas. Cependant, que se passe-t-il si je veux exécuter plusieurs applications à la fois et les faire redémarrer de manière indépendante selon les besoins? Avec toutes les fonctions de supervision de processus de fantaisie qu'inclut Erlang, je trouve incroyable que je n'arrive pas à faire quelque chose d'aussi simple que de redémarrer une application quand elle tombe en panne .... – Nick

3

Utilisez Monit, puis configurez votre application pour qu'elle se termine en utilisant un superviseur pour l'ensemble de l'application avec une fréquence de redémarrage raisonnable. Si l'application se termine, la machine virtuelle se termine et le monit redémarre tout.

Je ne pourrais jamais faire en sorte que Heart soit suffisamment fiable, car il ne redémarre qu'une seule fois la VM, et il ne gère pas bien le kill -9 de la machine virtuelle erlang.