Масштабирование Node.js

86

Я новичок в крупномасштабной серверной разработке. Я хочу написать сервер с использованием Node.js, но прежде чем продолжить, я хотел бы знать, каковы общие принципы масштабирования узла, скажем, до 20 запросов в секунду.

Сервис, который я пишу, будет в основном интерфейсом к базе данных, а также аутентификацией и проверкой входных данных.

Норнагон
источник
Что вы имеете в виду под «увеличением узла»? Запуск нескольких узловых процессов?
Тило
3
20 запросов в секунду - это довольно мало. Node.js должен поддерживать тысячи одновременных подключений. Только не выполняйте тяжелую обработку цикла, потому что это заблокирует весь интерпретатор. По сравнению с этим ваш вариант использования должен быть довольно легким. В Node соединения с базой данных автоматически порождаются потоками и обрабатываются асинхронно на уровне javascript.
slebetman

Ответы:

149

Балансировки нагрузки

Скорее всего, для самых простых сайтов масштабирование вообще не требуется. Только одна коробка поможет вам. После этого вы должны выполнить балансировку нагрузки, как вы упомянули, что почти одинаково для каждой архитектуры (например, вы говорите, что сначала можете запустить процессы с несколькими узлами. Но когда вы становитесь действительно большими, вам нужно больше блоков).

Пример балансировки нагрузки 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 запросов в секунду

Не беспокойтесь о node.js. Вы должны использовать redis в качестве хранилища данных, потому что это безумно быстро :). Когда вы используете node_redis, существует даже библиотека ac для узла .

npm install hiredis redis

Hiredis - это то, что дает вам отличную производительность, потому что он компилируется в код C внутри node. Вот несколько тестов Redis при использовании с 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

Когда вы смотрите на эти числа, 20 / с - НИЧЕГО :).

Аутентификация


Обновить:


Я много говорю об этом, но ради Бога, пожалуйста, не пытайтесь внедрить свою собственную систему аутентификации. Вероятно, это будет небезопасно (многое может пойти не так), много работы. Для аутентификации вы должны использовать facebook-connect, систему единого входа в Twitter и т. Д., Используя отличную библиотеку connect-auth . Тогда вы в безопасности, потому что у них есть эксперты, тестирующие там системы входа в систему на наличие дыр, и они также не передают пароли в виде обычного текста, но слава богу используют https. Я также ответил на тему для пользователя, который хотел использовать facebook-connect .

проверка входных данных

Для проверки ввода вы можете использовать узел-валидатор .

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

//Validate
check('test@email.com').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>'

Также существует эта библиотека форм, которая поможет вам создавать формы.

Альфред
источник
1
@nornagon добро пожаловать :). Особенно помните, что не нужно писать свою собственную систему входа;). Также Джефф Этвуд (автор Stackoverflow) настоятельно не советует этого! => blog.stackoverflow.com/2010/04/openid-one-year-later
Альфред
10
Вы можете использовать HAProxy для балансировки нагрузки WebSockets, поскольку nginx не будет работать :) Это при условии, что вы разрабатываете приложения, которые требуют от вас где-то использовать WebSockets! Просто дополнение к уже классному ответу @alfred.
Шрипад Кришна
5
Пример настройки HAProxy, если вы используете веб-сокеты: stackoverflow.com/questions/4360221/…
Шрипад Кришна
9
Хороший ответ. Однако я настоятельно рекомендую password.js вместо всех аутентификаций.
UpTheCreek
1
а как насчет паспорта вместо всех аутентификаций?
chovy 03