Node.js, tour d'horizon !

Alexis Kinsella, 4 novembre 2013

Node.js est un serveur JavaScript event driven non bloquant

Initié en 2009

Références

JavaScript ?

Côté serveur ?

Et mono threadé en plus ?

Oui, grâce au moteur V8 de Chrome !


Installation


                $ brew install node
            


... Ou bien via un installeur standard

Une première application

Une première application


                    var http = require('http');

                    http.createServer(function (req, res) {
                        res.writeHead(200, {'Content-Type': 'text/plain'});
                        res.end('Hello Open-XKE\n');
                    }).listen(9000, 'localhost');

                    console.log('Server running at http://localhost:9000/');
                

                    node app.js
                

Parlons un peu outillage ...

Un package manager / npmjs.org




                $ curl http://npmjs.org/install.sh | sh
            

Un task runner / gruntjs.com


                 $ npm install -g grunt-cli
                 $ npm install grunt --save-dev
             

Pourquoi Grunt ?

L'automatisation des tâches!!

Lancer une tâche ?


                    $ grunt {task}
                

Très bien, mais je peux faire quoi avec node.js ?

Très bien, mais je peux faire quoi avec node.js ?

  • APIs REST
  • Applications single page
  • Streaming de données
  • Application temps réel

Domaines d'application possible

  • Applications mobiles
  • Dashboards
  • Pari sportif
  • Messagerie instantanée
  • Gaming
  • ...

Et que devrais-je éviter de faire avec node.js ?

Et que devrais-je éviter de faire avec node.js ?

  • Les tâches gourmandes en CPU
  • Les tâches bloquantes

ExpressJS

ExpressJS est un framework web minimaliste and flexible, fournissant un ensemble robuste de fonctionalités pour construire des applications single et multi pages.

Librairies incontournables

requestClient REST
mongooseClient Mongo
passportAuthentification
momentGestion des dates
async ou QFlow Control
jsdomImplémentation DOM
oauth2orizeServeur OAuth
oauthClient OAuth
Socket.ioTemps réel
winstonLogging
node-mailerEnvoi de mails
node-soapExposer et consommer des web service SOAP
node-cronPlanificateur de tâches

MEAN Stack

Yet another acronym !

MEAN signifie

  • MongoDB
  • ExpressJS
  • Angular
  • Node.js

MEAN vu autrement

  • NoSQL Database oriented document
  • REST oriented layer
  • Single page application
  • Event based server

Failfast & résilience

Failfast et résilience

  • Gestion des erreurs spartiate. Si une erreur n'est pas catchée, alors le process tombe
  • Difficulté de catcher les erreurs
  • Outil de monitoring de processus obligatoire

Les Domaines à la rescousse !

  • Etre plus résilient face aux erreurs
  • Avoir un code sandboxé
  • Un domaine émet un évènement "error" quand il intercepte une erreur.

Les Domaines à la rescousse !


                domain.create()
                   .on('error', function (err) {
                        // handle error
                    })
                    .run(hello);
            

Clusterisation

La clusterisation

  • L'API de clusterisation, permettant de lancer de multiples instances du programmes
  • Idéalement, une instance par cpu
  • Ne supprime par le besoin de monitoring des process
  • API considérée comme instable par la documentation node.js
  • Dans les faits l'API évolue peu...

La clusterisation


                cluster = require("cluster")
                http = require("http")
                numCPUs = require("os").cpus().length

                if cluster.isMaster
                    # Fork workers.
                    i = 0
                    while i < numCPUs
                        cluster.fork()
                        i++
                        cluster.on "exit", (worker, code, signal) ->
                            console.log "worker " + worker.process.pid + " died"
                else
                    # Workers can share any TCP connection.
                    # In this case its a HTTP server
                    http.createServer((req, res) ->
                        res.writeHead 200
                        res.end "hello world\n"
                    ).listen 8000
            

Recluster, la clusterisation facile

  • Clusterise n'importe quelle application node.js (HTTP)
  • Reload automatique sur changement de fichier ...
  • Ou bien sur l'envoi d'un signal au process

                kill -s SIGUSR2 <cluster_pid>
            

Recluster, la clusterisation facile


                fs = require "fs"
                util = require "util"
                http = require "http"
                recluster = require "recluster"

                cluster = recluster "#{__dirname}/app.js"
                cluster.run()

                fs.watchFile "package.json", (curr, prev) ->
                    console.log "Package.json changed, reloading cluster..."
                    cluster.reload()

                process.on "SIGUSR2", ->
                    console.log "Got SIGUSR2, reloading cluster..."
                    cluster.reload()

                console.log "Spawned cluster, kill -s SIGUSR2 #{process.pid} to reload"
            

Zero Downtime Deployment

Zero downtime Deployment

  • Upstart + Respawn
  • Recluster => Nb workers == Nb CPU
  • NGINX => HTTP Proxy / HTTP 502 error page

Utilisation d'NGINX

  • Load balancing
  • Prise en charge des resources statiques
  • Compression GZip
  • Délégation des traitement dynamiques à Node.js
  • Affichage de pages spécifiques en cas d'erreur (502, 404, ...)

Daemonisation

Daemonisation d'applications - Upstart

+ -
Upstart
  • Support natif
  • Outil mature & stable
  • Absent de certaines distributions

Daemonisation d'applications - Upstart


                #!upstart
                description "Xebia Mobile Backend node.js server"
                author      "akinsella"

                start on (local-filesystems and net-device-up IFACE=venet0)
                stop on shutdown

                respawn
                respawn limit 99 5

                script
                    export HOME="/home/xebia"
                    echo $$ > /var/run/xebia-mobile-backend.pid
                    exec sudo -u xebia /home/xebia/xebia-mobile-backend.sh >> /var/log/xebia-mobile-backend.sys.log 2>&1
                end script

                pre-start script
                    # Date format same as (new Date()).toISOString() for consistency
                    echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Starting" >> /var/log/xebia-mobile-backend.sys.log
                end script

                pre-stop script
                    rm /var/run/xebia-mobile-backend.pid
                    echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Stopping" >> /var/log/xebia-mobile-backend.sys.log
                end script

            

Daemonisation d'applications - Forever

+ -
Forever
  • Outil spécifique Node.js
  • Outil mature & stable
  • Lancement manuel ou via un outil de type Upstart

Daemonisation d'applications - PM2

+ -
PM2
  • Outil dédié à Node.js
  • Capacité de clusterisation
  • Monitoring des noeuds
  • Streaming des logs
  • Problème de stabilité
  • Erreurs parfois peu claires, donc difficiles à corriger

Distributions

Distributions - StrongLoop

+ -
StrongLoop
  • Support
  • Tooling
  • Commiters node.js
  • Vendor lock-in en cas d'utilisation de fonctionnalités spécifiques

Hosting

Hosting - Cloud (PaaS)

+ -
Heroku, CloudFoundry, Nodejitsu, Appfog, DotCloud, ...
  • Facilité de déploiement
  • Elasticité des resources disponibles
  • Simplicité des déploiements
  • Pas de besoin d'expertise Ops
  • Manque de contrôle sur la plateforme (versions de Node et des middlewares)
  • Resources limitées par ce que propose l'offre
  • Cumulation d'offres Cloud pour couvrir les besoins d'une application complexe qui peut coûter cher

Hosting - Cloud (IaaS)

+ -
Amazon EC2, Rackspace, Ovh, Gandi, Azure, ...
  • Pas de gestion de parc de machine
  • Dashboard et outillage
  • AMI pré-configurées disponibles
  • Grande capacité à scaler et à organiser son déploiement selon les besoins
  • Offre VPN disponible
  • Pseudo standard
  • On doit se débrouille seul
  • Prix

Hosting - Self Hosting (VPS)

+ -
Serveur dédié
  • Prix
  • Maintenance du serveur
  • On doit se débrouille seul

Monitoring

Monitoring - NodeFly (StrongLoop)

+ -
NodeFly
  • Intégré à la distribution StrongLoop
  • Leader historique
  • Grille tarifaire complexe
  • Offre de type package (Disponible à travers l'offre StrongLoop)

Monitoring - Nodetime (AppDynamics)

+ -
Nodetime
  • Nombreuses métriques
  • Dashboard peu pratique

Monitoring - NewRelic

+ -
New Relic
  • Dashboard ultra complet
  • Multiples technologies, canaux, couches monitorables (Mobiles et système)
  • ??

Retours d'expérience

Questions ?

Merci !

Alexis Kinsella, Xebia France

Github: github.com/akinsella/node-overview

Références

Yammer http://www.davetech.com/blog/notes-two-years-nodejs-yammer
Groupon https://engineering.groupon.com/2013/misc/i-tier-dismantling-the-monoliths/?goback=%2Egde_3007928_member_5802431034863669248#%21
Walmart http://venturebeat.com/2012/01/24/why-walmart-is-using-node-js/
Ebay http://www.ebaytechblog.com/2013/05/17/how-we-built-ebays-first-node-js-application/
LinkedIn http://venturebeat.com/2011/08/16/linkedin-node/
Node.js à la conquête de l'entreprise http://blog.appfog.com/node-js-is-taking-over-the-enterprise-whether-you-like-it-or-not/
Trello (Fog Creek) http://blog.fogcreek.com/the-trello-tech-stack/
Uber http://www.joyent.com/developers/videos/node-js-office-hours-curtis-chambers-uber