NodeJS - Возможно ли иметь два отдельных кластера? - PullRequest
0 голосов
/ 18 февраля 2019

TL; DR

Возможно ли иметь два разных мастера кластера, которые не являются общими глобальными?Например, создание нового экземпляра myCluster = new cluster()?

Более длинная версия

После использования нового модуля кластера в NodeJS в течение некоторого времени я столкнулся с проблемой перекрытия двух отдельных кластеров.Две разные библиотеки (пакеты npm) обращаются к одному и тому же мастеру кластера, так как модуль кластера является глобальным в текущем запущенном процессе , независимо от того, откуда вы require.

При вызове cluster.workers из любой библиотеки будет перечислен каждый работник, созданный каждой библиотекой.

Все сходят с ума от того, насколько это легко и насколько эффективно, но после того, как столкнулись с проблемой двухВ библиотеках, использующих один и тот же кластер, я беспокоюсь о том, чтобы одна из них мешала другой, используя некоторые глобальные функции кластера, такие как cluster.disconnect(), или доступ к глобальному рабочему объекту cluster.workers.Я понимаю, что это достаточно одноразовый модуль «создайте самодостаточный кластер одноразовых работников, который можно легко перезапустить с помощью сторожевого таймера».

Но это самое простое решение для многопоточных задач, иприманки много беспокоит с child_process.Что если две библиотеки решат, что необходимо использовать cluster, но не потрудились отследить, какие рабочие принадлежат им, и вместо этого назвали нахальный

Object.values(cluster.workers).forEach(worker => worker.kill())

в качестве своей очистки?

Можно ли иметь два разных "экземпляра" или "пространства имен" для кластеров , чтобы не мешать другим мастерам кластеров?Или модуль кластера - это просто глобальная переменная, которую вы должны принять?

Я углубился в документацию, но из того, что я могу сказать, невозможно создать новый экземпляр кластера, вызвав myCluster = new cluster() илипередать какую-то уникальную личность разветвленным работникам.Я нахожу удивительным, что нет очевидного решения этой проблемы, особенно учитывая, что она нацелена на корпоративные приложения, где таких проблем не должно быть.

Тенденция (и какое-то время) в программировании заключается в том, чтобы сохранитьвдали от глобальных экземпляров и создавайте самодостаточные экземпляры, которые знают только то, что им нужно знать, так называемые «немые компоненты».Кластер - это довольно новое дополнение к NodeJS, они просто решили внедрить замечательную функцию?

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

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 28 марта 2019

Отвечая на мой собственный вопрос

После переключения на низкоуровневый модуль child_process я вернул обратно к использованию cluster по одной простой причине.Отладчик Node.js --inspect.

После долгих усилий по отладке другого пакета я отследил ошибку до зависимости, которая была моей собственной библиотекой, реализующей подход child_process.Он разветвлял child-process, используя унаследованный execArgs от родительского процесса, то есть child_process пытался подключиться к тому же порту инспектора, что и родительский процесс, молча завершался сбоем и вылетал.

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

VS Код имеет магический autoAttachChildProcesses, который обнаруживает разветвленные процессы, но только при использовании cluster, по крайней мере, в моем случае.Кажется, что cluster имеет некоторое сахарное покрытие вокруг процесса разветвления, что делает его более доступным для обнаружения и адаптации во время отладки, или, возможно, VS Code просто слушает исключительно cluster.fork().Я признал недостаток в том, чтобы сделать моего работника видимым для всего приложения в пользу более надежного взаимодействия с пользователями.

Это раздражающее поведение, которое имеет открытую проблему на GitHub: https://github.com/nodejs/node/issues/9435


Мой вывод заключается в том, что кластерный модуль предназначен для более унифицированного разветвления с более интеллектуальной обработкой и обнаружением процессов, пакеты просто должны будут уважать никогда не касаться cluster.workers или аналогичных глобальных функций, и вместо этого поддерживатьмассив их собственных работников, возвращенный cluster.fork().

0 голосов
/ 18 марта 2019

Ну нет.Или да.

Видите, поскольку кластеризация в терминах узла означает разветвление текущего процесса, фактически кластера нет - просто список вилок = рабочих.

Но: вы можете разветвляться и требоватьСценарий (или, если-еще в блок), вы хотите, чтобы вилка работала и сохраняла этого нового работника в свой собственный массив = cluster / fork_list.

У меня есть простой модуль поддержки, который разделяет рабочий скрипт (и просто загружает разные скрипты + обрабатывает связь): runworker

...