Skalowanie Node.js

86

Jestem całkiem nowy w programowaniu na dużą skalę po stronie serwera. Chcę napisać serwer przy użyciu Node.js, ale zanim przejdę dalej, chciałbym wiedzieć, jakie są ogólne zasady skalowania węzła do, powiedzmy, 20 zapytań na sekundę.

Usługa, którą piszę, będzie w dużej mierze interfejsem do bazy danych, a także uwierzytelnianiem i walidacją danych wejściowych.

nornagon
źródło
Co masz na myśli przez „skalowanie węzła w górę”? Rozpoczynasz procesy z wieloma węzłami?
Thilo,
3
20 zapytań na sekundę to dość mało. Node.js powinien obsługiwać tysiące jednoczesnych połączeń. Po prostu nie wykonuj ciężkiego przetwarzania w pętli, ponieważ zablokuje to cały interpreter. Twój przypadek użycia powinien być dość lekki w porównaniu. W Node połączenia z bazą danych są automatycznie tworzone w wątkach i obsługiwane asynchronicznie na poziomie JavaScript.
slebetman

Odpowiedzi:

149

Równoważenie obciążenia

Najprawdopodobniej w przypadku najprostszych witryn w ogóle nie potrzebujesz skalowania. Tylko jedno pudełko zapewni Ci ochronę. Następnie powinieneś zrobić równoważenie obciążenia, jak wspomniałeś, które jest prawie takie samo dla każdej architektury (tak jak mówisz, że możesz najpierw uruchomić wiele procesów węzłowych. Ale kiedy zrobisz się naprawdę duży, potrzebujesz więcej pudełek).

Przykład równoważenia obciążenia 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 zapytań na sekundę

Nie przejmuj się node.js. Powinieneś używać redis jako magazynu danych, ponieważ jest niesamowicie szybki :). Istnieje nawet biblioteka AC dla węzła, gdy używasz node_redis .

npm install hiredis redis

Hiredis zapewnia niesamowitą wydajność, ponieważ kompiluje się do kodu C w węźle. Oto kilka testów porównawczych redis używanych z 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

Jeśli spojrzysz na te liczby, 20 / s to NIC :).

Poświadczenie


Aktualizacja:


Mówię to dużo, ale na miłość boską, proszę, nie próbujcie wdrażać własnego systemu uwierzytelniania. Prawdopodobnie będzie to niebezpieczne (wiele może się nie udać), dużo pracy. Do uwierzytelniania należy używać Facebook-connect, jednokrotnego logowania na Twitterze itp., Korzystając z doskonałej biblioteki connect-auth . Wtedy jesteś bezpieczny, ponieważ mają ekspertów testujących tam systemy logowania pod kątem dziur, a także nie przesyłają haseł zwykłym tekstem, ale dzięki Bogu używają https. Odpowiedziałem również na temat użytkownika, który chciał skorzystać z facebook-connect .

walidacja danych wejściowych

Aby sprawdzić poprawność danych wejściowych, możesz użyć walidatora węzłów .

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

Dostępna jest również biblioteka formularzy, która ułatwia tworzenie formularzy.

Alfred
źródło
1
@nornagon witamy :). Szczególnie pamiętaj, aby nie pisać własnego systemu logowania;). Również Jeff Atwood (autor Stackoverflow) zdecydowanie odradza to! => blog.stackoverflow.com/2010/04/openid-one-year-later
Alfred
10
Możesz użyć HAProxy do równoważenia obciążenia WebSockets, ponieważ nginx nie zadziała :) Pod warunkiem, że tworzysz aplikacje, które wymagają gdzieś używania WebSockets! To tylko dodatek do już niesamowitej odpowiedzi @ alfred.
Shripad Krishna
5
Przykładowa konfiguracja HAProxy, w przypadku korzystania z gniazd internetowych: stackoverflow.com/questions/4360221/…
Shripad Krishna
9
Dobra odpowiedź. Zdecydowanie polecam jednak paszport.js w stosunku do wszystkich wpisów.
UpTheCreek
1
a co z paszportem zamiast ze wszystkimi uwierzytelnieniami?
chovy