Monthly Archives

2 Articles
NodeJS : Service et redémarrage automatique

NodeJS : Service et redémarrage automatique

Depuis que je travaillais sous NodeJS au travail, je me posais une question sur sa mise en place côté serveur. Comment l’exécuter en tant que service et comment faire pour qu’il se relance automatiquement en cas de gros crash. Effectivement, si votre serveur NodeJS crash à cause d’une erreur de développement, il se coupe. De plus, nodeJS se lance au premier plan, avec l’output sur stdin et stderr. Nous allons donc voir ces deux points pour avoir une solution solide aà mettre en place sur vos serveurs.

Prérequis

Pour commencer, je tiens à préciser que tous ces tests ont été effectués sur un Mac OSX, un serveur Ubuntu 12.10 64bits et un Ubuntu Desktop 12.10 64 bits. La version de NodeJS utilisée est la dernière en date au moment de l’écriture de cet article. À savoir la version 0.10.7.

Superviser les crash et mises à jour de son projet Node.

Comme dit plus haut, si jamais un crash non intercepté dans votre code a lieux, nodeJS affiche la stack trace dans son output et se quitte. Si vous exécutez votre script sur votre serveur et que l’erreur survient à 3h du matin, vous aurez l’agréable surprise de recevoir 5000 mails, autant de messages en absence pour vous dire qu’il y a un problème.

Je me suis donc tourneé vers différentes solutions existantes :

  • Forever : Si vous souhqitez seulement exécuter votre script en tant que daemon, alors forever est pour vous. Il vous permet de lancer/redémarrer/arrêter indépendamment chacun de vos scripts nodeJS. Seul souci pour ma problématique, il ne s’utilise pas comme un service unix.
  • nodemon : Nodemon relance votre script si un fichier a été modifié mais en cas d’erreur, il attends qu’un fichier soit modifié pour se relancer.
  • always : Ce script semble être abandonné car la fonctionnalité du redémarrage en cas d’erreur ne marche pas.
  • supervisor : Supervisor lance un script nodejs sur stdin, il redémarre le script tout seul en cas d’erreur et je crois même qu’il le redémarre aussi en cas de modification des fichiers sources.

Parmi tous ces choix, je me suis arrêté sur supervisor car il fait le minimum requis et il s’emboitera très bien avec la mise en place d’un service pour lancer le tout. Nous allons donc installer supervisor en module node global afin de pouvoir l’utiliser directement en commande au sein du terminal :

sudo npm install supervisor -g

Puis ensuite, pour lancer votre script :

supervisor script.js

Normalement, en cas d’erreur, supervisor relancera automatiquement votre script.

Mise en place du service

Maintenant que nous avons trouvé comment redémarrer automatiquement notre script nodeJS, nous allons le « transformer » en service. De plus, nous le rajouterons à notre liste des services à exécuter au démarrage.

Pour cela, nous allons utiliser un programme codeé en python du nom de supervisor. Encore un programme Supervisor ? Oui et il va nous permettre de faire ceci :

  • exécuter directement le programme avec un utilisateur propre
  • exécuter le programme directement dans le répertoire cible
  • définir les variables d’environnement

Autant de choses utiles pour ma problématique. Voici la procédure d’installation du programme supervisor :

sudo apt-get install python-setuptools
sudo easy_install supervisor

Ensuite, créez le fichier /etc/init.d/supervisord et placez y le code suivant afin d’utiliser supervisor comme un service :

#! /bin/bash -e

SUPERVISORD=/usr/local/bin/supervisord
PIDFILE=/tmp/supervisord.pid
OPTS="-c /etc/supervisord.conf"

test -x $SUPERVISORD || exit 0

. /lib/lsb/init-functions

export PATH="${PATH:+$PATH:}/usr/local/bin:/usr/sbin:/sbin"

case "$1" in
  start)
    log_begin_msg "Starting Supervisor daemon manager..."
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $SUPERVISORD -- $OPTS || log_end_msg 1
    log_end_msg 0
    ;;
  stop)
    log_begin_msg "Stopping Supervisor daemon manager..."
    start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE || log_end_msg 1
    log_end_msg 0
    ;;

  restart|reload|force-reload)
    log_begin_msg "Restarting Supervisor daemon manager..."
    start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile $PIDFILE
    start-stop-daemon --start --quiet --pidfile /var/run/sshd.pid --exec $SUPERVISORD -- $OPTS || log_end_msg 1
    log_end_msg 0
    ;;

  *)
    log_success_msg "Usage: /etc/init.d/supervisor
{start|stop|reload|force-reload|restart}"
    exit 1
esac

exit 0

Nous le rendons ensuite exécutable et nous le rajoutons aux programmes relancés au démarrage :

sudo chmod +x /etc/init.d/supervisord
sudo update-rc.d supervisord defaults

Maintenant que supervisord est mis en place, nous devons le configurer. Pour cela, nous allons générer le fichier de configuration par défaut comme ceci :

sudo echo_supervisord_conf > supervisord.conf
sudo mv supervisord.conf /etc/supervisord.conf

Avant de rajouter les scripts NodeJS à exécuter, nous éditons maintenant les configurations de supervisor en touchant au fichier /etc/supervisord.conf et en modificant les valeurs suivantes comme indiqué :

chmod=0777       ; sockef file mode (default 0700)
user=user        ; utiliateur devat exécuter les programmes de supervisord

Maintenant, rajoutez ce qui suit en fin du fichier de configuration pour chaque programmes serveur nodeJS que vous devez exécuter :

[program:yourapplicationname]
command=supervisor votrescript.js
directory=/application/directory
environment=NODE_ENV=production  

Voilà. Pour lancer votre serveur nodeJS, exécutez simplement la commande sudo service supervisord start et remplacez start par stop pour y mettre fin.

Conclusion

Je ne sais pas si ce que j’ai fait est la meilleure méthode mais c’est celle que j’ai trouvé être la plus simple à réaliser et qui répondait à mo problème. Bien entendu, supervisord peut lancer en même temps différentes applications dans différents langages. Si vous avez des questions, des conseils ou d’autres solutions, n’hésitez surtout pas à me les proposer. Sur ce, je vous souhaite un bon week-end.

Node Sender Preview

Node Sender Preview

Hello Everyone.

Today I’ll show you the preview of Library NodeJS I’m doing: Node-Sender

This library can simply send a Push to devices running Android, iOS, Blackberry or Windows Phone. For the moment, only the Android GCM Push is functional. Others should follow shortly. Similarly, for now you can not install this module via NPM. That will come when I finish all platforms.

Android Quick Start

var Sender = require('node-sender');

var sender = new Sender();

sender.send(
    Sender.TYPE_ANDROID,                // OS type
    { msge : "Test Message NodeJS" },   // message to send
    "Registration Id",                  // phone registration id(s)
    { apiKey : "Api-Key GCM" },         // settings
    function(err, response){            // callback
        console.log(err);
        console.log(response);
    }
);

Download

If you are curious and want to test this library, you can find it on my Github repository.