Dimensionando Node.js

86

Sou bastante novo no desenvolvimento do lado do servidor em grande escala. Quero escrever um servidor usando Node.js, mas antes de prosseguir, gostaria de saber quais são os princípios gerais para dimensionar o nó até, digamos, 20 consultas por segundo.

O serviço que estou escrevendo será em grande parte uma interface para um banco de dados, além de autenticação e validação de dados de entrada.

Nornagon
fonte
O que você quer dizer com "aumento de escala"? Iniciando vários processos de nó?
Thilo
3
20 consultas por segundo é bastante baixo. O Node.js deve ser capaz de lidar com milhares de conexões simultâneas. Só não faça processamento de loop pesado porque isso bloqueará todo o interpretador. Seu caso de uso deve ser bastante leve em comparação. No Node, as conexões de banco de dados são geradas automaticamente em threads e tratadas de forma assíncrona no nível do javascript.
slebetman

Respostas:

149

Balanceamento de carga

Muito provavelmente, para os sites mais simples, você não precisa de nenhum dimensionamento. Apenas uma única caixa o ajudará. Depois disso, você deve fazer o balanceamento de carga, como está mencionando, que é quase o mesmo para todas as arquiteturas (como você está dizendo que pode iniciar vários processos de nó primeiro. Mas quando você ficar muito grande, precisará de mais caixas).

Exemplo de balanceamento de carga 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

Sem problemas para node.js. Você deve usar redis como seu armazenamento de dados porque ele é extremamente rápido :). Existe até uma biblioteca AC para node quando você usa node_redis .

npm install hiredis redis

Hiredis é o que lhe dá um desempenho incrível porque compila para o código C dentro do nó. Aqui estão alguns benchmarks do redis quando usados ​​com o 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

Quando você olha para esses números, então 20 / s não é NADA :).

Autenticação


Atualizar:


Estou dizendo muito isso, mas pelo amor de Deus, por favor, não tente implementar seu próprio sistema de autenticação. Provavelmente não será seguro (muita coisa pode dar errado), muito trabalho. Para autenticação, você deve usar facebook-connect, twitter single sign-in, etc. usando a excelente biblioteca connect-auth Então você está seguro porque eles têm especialistas testando seus sistemas de login para falhas e também não transmitem senhas via texto simples, mas graças a Deus, use https. Eu também respondi um tópico para um usuário que queria usar o Facebook Connect .

validação de dados de entrada

Para validar a entrada, você pode usar o validador de nó .

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>'

Também existe esta biblioteca de formulários para ajudá-lo a criar formulários.

Alfred
fonte
1
@nornagon de nada :). Em especial, lembre-se de não escrever seu próprio sistema de login;). Jeff Atwood (autor de Stackoverflow) também desaconselha isso! => blog.stackoverflow.com/2010/04/openid-one-year-later
Alfred
10
Você pode usar o HAProxy para balancear a carga de WebSockets já que o nginx não funcionará :) Isso é fornecido para você desenvolver aplicativos que requerem o uso de WebSockets em algum lugar! Apenas um acréscimo à resposta já incrível de @Alfred.
Shripad Krishna
5
Um exemplo de configuração do HAProxy, caso você use websockets: stackoverflow.com/questions/4360221/…
Shripad Krishna
9
Boa resposta. Eu recomendo fortemente o passport.js em vez de everyauth.
UpTheCreek
1
que tal passaporte em vez de everyauth?
chovy