Разница режимов кластера и вилки в PM2

89

Я много искал, чтобы разобраться в этом вопросе, но не получил четкого объяснения. Есть ли только одно отличие: кластерное приложение можно масштабировать, а разветвленное - нельзя?

Публичный сайт PM2 объясняет, что кластерный режим может выполнять эту функцию, но никто не говорит о плюсах режима Fork (возможно, он может быть NODE_APP_INSTANCEпеременным).

Мне кажется, что Cluster может быть частью Fork, потому что Fork, похоже, используется в целом. Итак, я полагаю, что Fork означает просто «разветвленный процесс» с точки зрения PM2, а Cluster означает «разветвленный процесс, который можно масштабировать». Тогда зачем мне использовать режим вилки?

Джинён Ким
источник

Ответы:

121

Основное различие между fork_modeи cluster_modeзаключается в том, что он приказывает pm2 использовать api child_process.fork или api кластера .

Что это значит внутри?

Режим вилки

Возьмем forkрежим как основной порождение процесса. Это позволяет изменить exec_interpreter, чтобы вы могли запускать сервер phpили pythonсервер с pm2. Да, exec_interpreterэто «команда», используемая для запуска дочернего процесса. По умолчанию pm2 будет использовать nodeчто- pm2 start server.jsто вроде:

require('child_process').spawn('node', ['server.js'])

Этот режим очень полезен, поскольку открывает множество возможностей. Например, вы можете запустить несколько серверов на предварительно установленных портах, которые затем будут сбалансированы с помощью HAProxy или Nginx.

Кластерный режим

clusterБудет работать только с , nodeкак это exec_interpreterпотому , что она будет иметь доступ к nodejs кластера модуля (например: isMaster, forkметоды и т.д.). Это отлично подходит для управления процессами с нулевой конфигурацией, потому что процесс будет автоматически разветвляться в нескольких экземплярах. Например pm2 start -i 4 server.js, запустит 4 экземпляра server.jsи позволит модулю кластера выполнять балансировку нагрузки.

Союка
источник
3
вопрос, основанный на вашем ответе здесь: у меня есть вариант использования, который мне нужен, скажем, 30 экземпляров моего приложения node.js, созданных с уникальным, предопределенным номером порта (: от 3000 до: 3030), и каждый из экземпляров обрабатывает определенная группа пользователей, которые будут иметь доступ только через назначенный им порт. Поэтому я не хочу, чтобы главный процесс выполнял балансировку нагрузки, а просто запускал (и продолжал работать) дочерние процессы. Это возможно? Или он попытается распределить нагрузку только на все порожденные дочерние процессы?
tamak
3
Я бы использовал программный API pm2 для запуска 30 процессов в fork_mode и использовал бы что-то еще в качестве балансировщика нагрузки между 30 портами. Вы также можете использовать pm2 start -i 30 app.jsи позволить кластеру nodejs выполнять работу.
soyuka
11
Примечание: в cluster modeглавном процессе есть единственная точка отказа.
Карл Покус
40

Node.js - однопоточный.

Это означает, что только 1 ядро ​​вашего четырехъядерного процессора Intel может выполнять приложение узла.

Это называется: fork_mode.

Мы используем его для местных разработчиков .

pm2 start server.js -i 0 помогает запустить 1 поток узла на каждом ядре вашего процессора.

И автоматическая балансировка нагрузки для поступающих запросов без сохранения состояния.

В том же порту .

Мы называем это: cluster_mode.

Которая используется для производительности на производстве .

Вы также можете сделать это на локальном разработчике, если хотите провести стресс-тест своего ПК :)

Хаотан
источник
2
спасибо, это многое проясняет в моих мыслях о nodejs
Агравал
1
отличное объяснение !!
Пике
1
Node.js не является однопоточным, существует (в настоящее время) один пользовательский поток, но он определенно поддерживается пулом потоков libuv.
Бенджамин Грюнбаум
1
@BenjaminGruenbaum Согласен с вами. Мое заявление следует понимать в предположении, что я не говорю слишком глубоко до уровня
libuv
16

Документация и источники здесь действительно вводят в заблуждение.

Читая об этом в источниках, кажется, единственная разница заключается в том, что они используют либо узел, clusterлибо child_processAPI. Поскольку clusterиспользуется последний, вы фактически делаете то же самое. Просто в таверне stdioпроисходит намного больше обычаев fork_mode. Также clusterможет передаваться только через строки, а не объекты.

По умолчанию вы используете fork_mode. Если вы передадите -i [number]опцию -option, вы попадете в то cluster_mode, к чему обычно стремитесь w / pm2.

Также fork_modeэкземпляр, вероятно, не может прослушивать тот же порт из-за EADDRINUSE. cluster_modeможет. Таким образом, вы также можете структурировать свое приложение для работы на одном порту с автоматической балансировкой нагрузки. Тогда вы должны создавать приложения без состояния, например, sessions, dbs.

Eljefedelrodeodeljefe
источник
1
Я все еще в замешательстве. clusterвстроенный модуль использует child_processвнутренне? и ваше предложение: если мне нужна гибкость stdio, я должен использовать Fork-mode?
Джинён Ким
Это stdioчто-то вроде pm2реализации. Не беспокойся об этом. Вы хотите использовать cluster_modeв производственной среде, потому что это укрепляет ваш экземпляр, поскольку он запускает -i [number]экземпляры в фоновом режиме. Используйте, fork_modeесли в закалке нет необходимости или вам нужны лучшие журналы и прочее.
eljefedelrodeodeljefe
1
Также очевидно, что cluster_modeиспользует больше ресурсов вашей системы, потому что вы выполняете -i [number]процессы.
eljefedelrodeodeljefe
Хотя я тепло оценил ваш ответ, я даже сейчас не понял сути. Большинство ваших объяснений являются естественными (например, использование CLI cluster_mode, балансировка нагрузки cluster_mode, cluster_modeиспользование большего количества ресурсов ...). Вот почему я не голосовал. Не могли бы вы объяснить оба простых варианта использования? В каждом случае должно быть обоснование, почему он выбрал свой режим.
Джинён Ким
@eljefedelrodeodeljefe Не могли бы вы объяснить больше о том, что «вам нужно создавать приложения без состояния, например, сеансы, базы данных»? Почему приложение должно быть без состояния?
STEN