Escalado de Node.js

86

Soy bastante nuevo en el desarrollo del lado del servidor a gran escala. Quiero escribir un servidor usando Node.js, pero antes de seguir adelante, me gustaría saber cuáles son los principios generales para escalar el nodo hasta, digamos, 20 consultas por segundo.

El servicio que estoy escribiendo será en gran parte una interfaz para una base de datos, además de la autenticación y validación de los datos de entrada.

nornagon
fuente
¿Qué quieres decir con "escalar el nodo"? ¿Iniciar múltiples procesos de nodos?
Thilo
3
20 consultas por segundo es bastante bajo. Node.js debería poder manejar miles de conexiones simultáneas. Simplemente no haga un procesamiento de bucle pesado porque bloqueará todo el intérprete. Su caso de uso debería ser bastante ligero en comparación. En Node, las conexiones de base de datos se generan automáticamente en subprocesos y se manejan de forma asincrónica en el nivel de JavaScript.
slebetman

Respuestas:

149

Balanceo de carga

Lo más probable es que para los sitios más simples no necesite escalar en absoluto. Solo una caja lo cubrirá. Después de eso, debe hacer el balanceo de carga como lo está mencionando, que es casi lo mismo para todas las arquitecturas (como si estuviera diciendo que podría iniciar varios procesos de nodos primero. Pero cuando se vuelve realmente grande, necesita más cajas).

Ejemplo de equilibrio de carga de 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 consultas por segundo

No se preocupe por node.js. Deberías usar redis como tu almacén de datos porque es increíblemente rápido :). Incluso hay una biblioteca de CA para el nodo cuando usa node_redis .

npm install hiredis redis

Hiredis es lo que le brinda un rendimiento excelente porque se compila en código C dentro del nodo. Aquí hay algunos puntos de referencia de redis cuando se usa con 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

Cuando miras esos números, 20 / s NO ES NADA :).

Autenticación


Actualizar:


Estoy diciendo esto mucho, pero por el amor de Dios, no intente implementar su propio sistema de autenticación. Probablemente no sea seguro (muchas cosas pueden salir mal), mucho trabajo. Para la autenticación, debe usar facebook-connect, twitter single sign-in, etc. usando la excelente biblioteca connect-auth . Entonces está seguro porque tienen expertos que prueban sus sistemas de inicio de sesión en busca de agujeros y tampoco transmiten contraseñas a través de texto plano, pero gracias a Dios, use https. También respondí un tema para un usuario que quería usar facebook-connect .

validación de datos de entrada

Para validar la entrada, puede usar 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>'

También existe esta biblioteca de formularios para ayudarlo a crear formularios.

Alfredo
fuente
1
@nornagon de bienvenida :). Especialmente recuerde no escribir su propio sistema de inicio de sesión;). ¡También Jeff Atwood (autor de Stackoverflow) lo desaconseja! => blog.stackoverflow.com/2010/04/openid-one-year-later
Alfred
10
Puede usar HAProxy para equilibrar la carga de WebSockets ya que nginx no funcionará :) ¡Esto siempre que esté desarrollando aplicaciones que requieran que use WebSockets en alguna parte! Solo una adición a la ya asombrosa respuesta de @ alfred.
Shripad Krishna
5
Un ejemplo de configuración de HAProxy, en caso de que use websockets: stackoverflow.com/questions/4360221/…
Shripad Krishna
9
Buena respuesta. Sin embargo, recomiendo encarecidamente passport.js sobre everyauth.
UpTheCreek
1
¿Qué pasa con el pasaporte en lugar de everyauth?
Chovy