Mise à l'échelle de Node.js

86

Je suis assez nouveau dans le développement côté serveur à grande échelle. Je veux écrire un serveur en utilisant Node.js, mais avant d'aller plus loin, j'aimerais savoir quels sont les principes généraux pour faire évoluer le nœud jusqu'à, disons, 20 requêtes par seconde.

Le service que j'écris sera en grande partie une interface vers une base de données, plus l'authentification et la validation des données d'entrée.

Nornagon
la source
Qu'entendez-vous par «mise à l'échelle du nœud»? Démarrage de plusieurs processus de nœuds?
Thilo
3
20 requêtes par seconde est assez faible. Node.js devrait être capable de gérer des milliers de connexions simultanées. Ne faites pas de traitement de boucle lourd car cela bloquera tout l'interpréteur. Votre cas d'utilisation doit être assez léger en comparaison. Dans Node, les connexions à la base de données sont automatiquement générées vers les threads et gérées de manière asynchrone au niveau javascript.
slebetman

Réponses:

149

L'équilibrage de charge

Très probablement, pour les sites les plus simples, vous n'avez pas du tout besoin de mise à l'échelle. Une seule boîte vous couvrira. Après cela, vous devriez faire un équilibrage de charge comme vous le dites, qui est presque le même pour chaque architecture (comme vous le dites, vous pouvez commencer par lancer plusieurs processus de nœuds. Mais lorsque vous devenez vraiment gros, vous avez besoin de plus de boîtes).

Exemple d'équilibrage de charge Nginx :

http {
  upstream myproject {
    server 127.0.0.1:8000 weight=3;
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;    
    server 127.0.0.1:8003;
  }

  server {
    listen 80;
    server_name www.domain.com;
    location / {
      proxy_pass http://myproject;
    }
  }
}

Redis

20 requêtes par seconde

Pas de soucis pour node.js. Vous devriez utiliser redis comme magasin de données car il est insensé rapide :). Il existe même une bibliothèque ac pour node lorsque vous utilisez node_redis .

npm install hiredis redis

Hiredis est ce qui vous donne des performances exceptionnelles car il se compile en code C à l'intérieur du nœud. Voici quelques repères de redis lorsqu'il est utilisé avec hiredis.

PING: 20000 ops 46189.38 ops/sec 1/4/1.082
SET: 20000 ops 41237.11 ops/sec 0/6/1.210
GET: 20000 ops 39682.54 ops/sec 1/7/1.257
INCR: 20000 ops 40080.16 ops/sec 0/8/1.242
LPUSH: 20000 ops 41152.26 ops/sec 0/3/1.212
LRANGE (10 elements): 20000 ops 36563.07 ops/sec 1/8/1.363
LRANGE (100 elements): 20000 ops 21834.06 ops/sec 0/9/2.287

Quand vous regardez ces chiffres, alors 20 / s n'est RIEN :).

Authentification


Mise à jour:


Je dis beaucoup cela, mais pour l'amour de Dieu, n'essayez pas de mettre en œuvre votre propre système d'authentification. Cela va probablement être dangereux (beaucoup de choses peuvent mal tourner), beaucoup de travail. Pour l'authentification, vous devez utiliser facebook-connect, connexion unique Twitter, etc. en utilisant l'excellente bibliothèque connect-auth . Ensuite, vous êtes protégé car ils ont des experts qui testent les systèmes de connexion pour détecter les trous et ne transmettent pas non plus les mots de passe via du texte brut, mais merci à Dieu d'utiliser https. J'ai également répondu à un sujet pour un utilisateur souhaitant utiliser facebook-connect .

validation des données d'entrée

Pour valider l'entrée, vous pouvez utiliser node-validator .

var check = require('validator').check,
    sanitize = require('validator').sanitize

//Validate
check('[email protected]').len(6, 64).isEmail();       //Methods are chainable
check('abc').isInt();                               //Throws 'Invalid integer'
check('abc', 'Please enter a number').isInt();      //Throws 'Please enter a number'
check('abcdefghijklmnopzrtsuvqxyz').is(/^[a-z]+$/);

//Sanitize / Filter
var int = sanitize('0123').toInt();                  //123
var bool = sanitize('true').toBoolean();             //true
var str = sanitize(' \s\t\r hello \n').trim();      //'hello'
var str = sanitize('aaaaaaaaab').ltrim('a');        //'b'
var str = sanitize(large_input_str).xss();
var str = sanitize('&lt;a&gt;').entityDecode();     //'<a>'

Il existe également cette bibliothèque de formulaires pour vous aider à créer des formulaires.

Alfred
la source
1
@nornagon votre bienvenue :). N'oubliez surtout pas de ne pas écrire votre propre système de connexion;). Jeff Atwood (auteur de Stackoverflow) le déconseille vivement! => blog.stackoverflow.com/2010/04/openid-one-year-later
Alfred
10
Vous pouvez utiliser HAProxy pour équilibrer la charge des WebSockets car nginx ne fonctionnera pas :) Ceci est à condition que vous développiez des applications qui vous obligent à utiliser WebSockets quelque part! Juste un ajout à la réponse déjà géniale de @ alfred.
Shripad Krishna
5
Un exemple de configuration HAProxy, au cas où vous utiliseriez des websockets: stackoverflow.com/questions/4360221/…
Shripad Krishna
9
Bonne réponse. Je recommanderais fortement passeport.js à tout le monde.
UpTheCreek
1
qu'en est-il du passeport au lieu de tout le monde?
chovy