Подтвердить что ты не робот

Масштабируемая архитектура приложения Node.js

В прошлом я играл с Node.js только на моем локальном компьютере, поэтому у меня есть опыт работы с одиночными процессами Node.js. Теперь я хотел бы создать веб-приложение, которое я мог бы опубликовать в Интернете.

Это веб-приложение будет чем-то вроде многопользовательской игры - используя Socket.IO для обмена данными между клиентом и сервером, Express для обработки HTTP-запросов, grunt для управления задачами и т.д. Я хотел бы использовать другие пакеты NPM для различных задач.

Я хотел бы создать архитектуру этого приложения для

  • включить горизонтальную масштабируемость (позже, когда у меня много посетителей, мне не нужно переписывать все приложение)
  • минимизировать зависимости от разных сред исполнения (чтобы максимизировать переносимость)

Как я могу достичь этого, используя Node?

Я предполагаю, что архитектура высокого уровня будет состоять из:

  • Различные серверные процессы (каждый процесс запускает экземпляр Express и обрабатывает входящие HTTP-запросы).
  • Где-то должен быть балансировщик нагрузки.
  • Необязательно: фоновые процессы, которые могут периодически запускаться и обрабатывать "общие данные"

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

Чтобы все было просто, сначала мне не нужно сохранять эти общие данные, поэтому я думаю, что я должен использовать хранилище данных в памяти, такое как Redis.

Общая картина будет выглядеть примерно так:

Sample Node.js application architecture

В этой конструкции возникают некоторые вопросы:

Как создать процессы?

Должен ли я использовать модули Node child_process или cluster и запускать рабочие процессы вручную? Кстати, возможно ли вообще начать их вручную, например, если я разверну свое приложение для Heroku или Nodejitsu?

ИЛИ: is there a better way to store these information in a config file?

Я имею в виду, было бы лучше, если бы я мог настроить, сколько экземпляров сервера я не хочу редактировать код, но запись в config.

Границы системы?

Если я запускаю процессы вручную, то (я думаю) все процессы будут запускаться на одном и том же (виртуальном) сервере.

Если у этого сервера есть, скажем, 4 ядра процессора, то вы можете создать 4 Node экземпляра максимум, потому что если вы еще больше создадите, ваш процессор сделает контекстные переключатели, которые разрушат общую производительность.

Что мне нужно сделать, если мне нужно больше экземпляров процессов? Скажем, мне нужно 100 экземпляров сервера. Нужно ли развертывать мое приложение на 25 серверах и создавать 4 процесса на каждом сервере?

Мне кажется, что хостинговые сервисы вроде Nodejitsu каким-то образом скрывают этот пограничный уровень системы от вас, но я не вижу, как это работает на практике.

Особенно, что есть этот компонент поставщика общих данных. Я предполагаю, что этот провайдер (например, сервер Redis) должен работать на другом сервере, чтобы он был доступен для всех процессов. Но в этом случае это может легко стать узким местом, не так ли?

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

Если я использую какую-либо услугу хостинга, мне нужно самостоятельно настроить уровень балансировки нагрузки?


Edit:

Чтобы ответить на несколько практических вопросов: на первом этапе я хочу легко обрабатывать 4-500 одновременных пользователей (соединения Socket.IO). Это количество посетителей, которых я могу реально достичь.Суб >

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

Насколько мне известно, облачные сервисы хостинга, такие как Heroku и Nodejitsu, могут быть легко адаптированы к этим сценариям - вам просто нужно увеличить количество рабочих/динозавров и т.д., но оно работает только в том случае, если вы имеете право архитектуры приложений.

Что касается общих данных: я не хочу его останавливать. Я просто хочу сохранить его в памяти. Некоторый общий поставщик данных, с одной стороны, необходим из-за Socket.IO - один пользователь сможет отправить сообщение пользователю, который находится в другом "node". Для этого я бы использовал Redis в качестве поставщика общих данных. Количество транзакций, которые Redis должен обрабатывать, равно количеству отправленных/полученных сообщений с Socket.IO, ~ 1000-1500 сообщений/сек.

С другой стороны, необходим какой-то общий поставщик данных, потому что я хочу подключить пользователей на основе нескольких критериев. Позднее фоновые процессы периодически пересчитывали/уточняли вероятность ( "вес" ) этих соединений. У меня уже есть идея, как реализовать эффективную структуру данных для обработки быстрых вставок/удалений в эту таблицу в памяти. Таким образом, компонент "общий поставщик данных" будет состоять из некоторого кода на стороне сервера (возможно, Node.js), который может хранить эти соединения.Суб >

Я знаю его TL; DR, но надеюсь, что он ответит на все ваши технические вопросы по этой проблеме.:)

4b9b3361

Ответ 1

Хорошо, это много, чтобы пройти. Во-первых, ваше разделение проблем является подходящим, вам понадобится способ для обработки сообщений, это может быть через экземпляр Redis или другую систему pub/sub или req/res (будь то redis, kue, zmq и т.д.). ПРИМЕЧАНИЕ. Вероятно, вам все равно придется обманывать использование ваших данных/сообщений, если вы растете значительно, по крайней мере, насколько это возможно. Это можно облегчить, если вы используете более сложную систему очереди сообщений (Rabbit или другой AMQP).

Кажется, ваша главная задача - управление процессами. В общем, если вы используете Heroku, вы должны иметь возможность масштабировать один процесс за node, но тогда вам все равно понадобится ваш координатор node (s). Если вы являетесь владельцем собственного хостинга (не через герольку или тому подобное), вы должны посмотреть pm2 или forever... Затем вы можете вызвать несколько экземпляров...

По большей части ваши проблемы с логистикой/инфраструктурой будут зависеть от ваших потребностей. Не говоря уже о более новых стратегиях с участием CI/CD, докеров и других. Или используйте свою базу данных.