[ Эта публикация актуальна по состоянию на 2012-09-02 (новее, чем указано выше). ]
Node.js абсолютно масштабируется на многоядерных машинах.
Да, Node.js - один поток на процесс.Это очень обдуманное проектное решение, устраняющее необходимость иметь дело с семантикой блокировки.Если вы не согласны с этим, вы, вероятно, еще не понимаете, насколько безумно сложно отлаживать многопоточный код.Для более глубокого объяснения модели процесса Node.js и почему она работает таким образом (и почему она НИКОГДА не будет поддерживать несколько потоков), прочитайте мой другой пост .
Итак, как мне взятьПреимущество моего 16-ядерного блока?
Два способа:
- Для больших сложных вычислительных задач, таких как кодирование изображений, Node.js может запускать дочерние процессы или отправлять сообщения дополнительным рабочим процессам.В этом проекте у вас был бы один поток, управляющий потоком событий, а N процессов, выполняющих сложные вычислительные задачи и пережевывающих другие 15 процессоров.
- Для масштабирования пропускной способности веб-службы вам необходимо запустить несколько Node.js.серверы на одной коробке, по одному на ядро и распределенный трафик запросов между ними.Это обеспечивает отличную привязку к процессору и масштабирует пропускную способность почти линейно с количеством ядер.
Масштабирование пропускной способности веб-службы
Начиная с версии 6.0.X Node.js модуль кластера прямо из коробки, что упрощает настройку нескольких рабочих узлов, которые могут прослушивать один порт.Обратите внимание, что это НЕ то же самое, что более старый модуль кластера Learnboost, доступный через npm .
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
http.Server(function(req, res) { ... }).listen(8000);
}
Рабочие будут бороться за принятие новых соединений, и наименее загруженный процесс наиболее вероятенпобеждать.Он работает довольно хорошо и может неплохо увеличить пропускную способность на многоядерном процессоре.
Если у вас достаточно нагрузки, чтобы позаботиться о нескольких ядрах, вам нужно будет сделать еще несколько вещей:
Запустите службу Node.js через веб-прокси, например Nginx или Apache - то, что может регулировать соединение (если вы не хотите перегрузки)условия, чтобы полностью убрать флажок), переписать URL-адреса, предоставить статический контент и прокси-серверы других вспомогательных служб.
Периодически перезапускайте рабочие процессы.В случае продолжительного процесса даже небольшая утечка памяти в конечном итоге приведет к увеличению.
Настройка сбора / мониторинга журналов
PSЕсть обсуждение между Аароном и Кристофером в комментариях к другому посту (на момент написания статьи это самый верхний пост).Несколько комментариев по этому поводу:
- Модель общего сокета очень удобна для того, чтобы позволить нескольким процессам прослушивать один порт и конкурировать на прием новых соединений.Концептуально, вы могли бы подумать о том, что предварительно разветвленный Apache сделает это со значительным предупреждением, что каждый процесс примет только одно соединение, а затем умрет.Потеря эффективности для Apache приводит к накладным расходам на создание новых процессов и не имеет ничего общего с операциями с сокетами.
- Для Node.js наличие N работников, конкурирующих на одном сокете, является чрезвычайно разумным решением.Альтернативой является настройка встроенного внешнего интерфейса, такого как Nginx, и передача этого прокси-трафика отдельным работникам, чередуя работников для назначения новых соединений.Два решения имеют очень похожие характеристики производительности.И поскольку, как я упоминал выше, вы, вероятно, захотите, чтобы Nginx (или его альтернатива) в любом случае стоял перед вашим нодовым сервисом, выбор здесь действительно:
Shared Ports: nginx (port 80) --> Node_workers x N (sharing port 3000 w/ Cluster)
против
Отдельные порты: nginx (port 80) --> {Node_worker (port 3000), Node_worker (port 3001), Node_worker (port 3002), Node_worker (port 3003) ...}
Возможно, есть некоторые преимущества при настройке отдельных портов (возможно меньшее количество соединений между процессами, более сложные решения по распределению нагрузки,и т. д.), но это определенно требует больше усилий, а встроенный кластерный модуль - это альтернатива с низкой сложностью, которая подходит для большинства людей.