Что было бы лучше для параллельных задач на узле.Джей? Волокна? Веб-работники? или нитки?


я наткнулся на узел.js когда-то давно и очень нравится. Но вскоре я обнаружил, что ему очень не хватает способности выполнять задачи с интенсивным процессором. Итак, я начал гуглить и получил эти ответы, чтобы решить проблему: волокна, веб-рабочие и потоки (thread-a-gogo). Теперь, какой из них использовать, является путаницей, и один из них определенно нужно использовать - в конце концов, какова цель иметь сервер, который просто хорош в IO и ничего больше? Предложения нужно!

обновление:

Я думал о пути-поздно; просто нужны предложения по этому поводу. Теперь, что я думал об этом: давайте иметь несколько потоков (с помощью thread_a_gogo или, может быть, webworkers). Теперь, когда нам нужно больше их, мы можем создать больше. Но будет некоторый предел над процессом творения. (не подразумевается системой, но, вероятно, из-за накладных расходов). Теперь, когда мы превысим лимит, мы можем развить новый узел и начать создавать потоки над ним. Таким образом, это может продолжаться до тех пор, пока мы не достигнем некоторого предела (в конце концов, процессы тоже имеют большие накладные расходы). Когда этот предел достигнут, мы начинаем ставить задачи в очередь. Всякий раз, когда поток становится свободным, ему будет назначена новая задача. Таким образом, это может идти гладко.

Так вот о чем я подумал. Это хорошая идея? Я немного Новичок во всем этом процессе и потоках, поэтому не имею никакого опыта в этом. Пожалуйста, поделитесь своим мнением.

спасибо. :)

7 106

7 ответов:

узел имеет совершенно другую парадигму, и как только он правильно захвачен, легче увидеть этот другой способ решения проблем. Вам никогда не нужно несколько потоков в узле приложения(1), потому что у вас есть другой способ сделать то же самое. Вы создаете несколько процессов; но это очень сильно отличается, например, от того, как работает Prefork mpm веб-сервера Apache.

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

- Эй, Хасан, я полагаю, ты либо новичок, либо очень старая школа со времен моего деда!!! Почему бы вам не создать несколько потоков и сделать это намного быстрее?

-- О, у нас есть только одно ядро процессора.

-- ну и что? Создать несколько потоков человек, сделать это быстрее!

-- это не работает так. Если я создаю потоки, я буду делать это медленнее. Потому что я буду добавлять много накладных расходов в систему для переключения между потоками, пытаясь дать им только количество времени, и внутри моего процесса, пытаясь общаться между этими потоками. В дополнение ко всем этим фактам мне также придется подумать о том, как я разделю одну работу на несколько частей, которые можно сделать параллельно.

-- Хорошо, хорошо, я вижу, что вы бедный. Давайте использовать мой компьютер, он имеет 32 ядра!

-- Вау, ты потрясающий мой дорогой друг, спасибо тебе большое. Я ценю это!

затем мы возвращаемся к работе. Теперь у нас есть 32 ядер процессора, благодаря нашему богатому другу. Правила мы должны соблюдать изменились. Теперь мы хотим использовать все это богатство нам дано.

чтобы использовать несколько ядер, нам нужно найти способ разделить нашу работу на части, которые мы можем обрабатывать параллельно. Если бы это был не узел, мы бы использовали потоки для этого; 32 потока, по одному для каждого ядра процессора. Однако, поскольку у нас есть узел, мы создадим 32 узловых процесса.

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

-- Эй, Хасан, ты все еще работаешь однопоточный? Да что с тобой такое, мужик? Я только что дал вам то, что вы хотели. У тебя больше нет оправданий. Создавайте потоки, заставляйте их работать быстрее.

-- Я разделила работу на части и каждый процесс будет работать на одной из этих штук в параллель.

-- почему вы не создаете темы?

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

-- нет Хорошо, я крут, я просто не понимаю, почему вы не используете темы?

-- Спасибо за компьютер. :) Я уже разделил работу на части, и я создаю процессы для работы над этими частями параллельно. Все ядра процессора будут полностью использованы. Я мог бы сделать это с потоками вместо процессов; но Node имеет такой способ, и мой босс парт Таккар хочет, чтобы я использовал Node.

-- ладно, дайте мне знать, если вам нужен другой компьютер. : p

если я создам 33 процесса, а не 32, планировщик операционной системы будет приостанавливать поток, запускать другой, приостанавливать его после нескольких циклов, снова запускать другой... Это ненужные накладные расходы. Я этого не хочу. На самом деле, в системе с 32 ядрами я бы даже не хотел создавать ровно 32 процесса, 31 может быть лучше. Потому что это не только мое приложение, которое будет работать на этой системе. Оставляя немного места для других вещей может быть хорошо, особенно если у нас есть 32 номера.

Я считаю, что мы сейчас находимся на одной странице о полном использовании процессоров для CPU-интенсивные задачи.

-- Хм, Хасан, прости, что немного над тобой издеваюсь. Думаю, теперь я понимаю тебя лучше. Но есть еще кое-что, что мне нужно объяснить: что такое весь шум о запуске сотен потоков? Я везде читал, что потоки гораздо быстрее создавать и тупые, чем процессы разветвления? Вы разветвляете процессы вместо потоков, и вы думаете, что это самое высокое, что вы получите с узлом. Тогда узел не подходит для такого рода работы?

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

-- и что? Узел не подходит для этого?

-- Node отлично подходит для этого, хотя потоки тоже могут быть хорошими. Что касается накладных расходов на создание потоков/процессов; на вещи, которые вы повторяете много, каждая миллисекунда считается. Тем Не Менее, Я создайте только 32 процесса, и это займет совсем немного времени. Это произойдет только один раз. Это не будет иметь никакого значения.

-- когда я хочу создать тысячи потоков, то?

-- вы никогда не хотите создавать тысячи потоков. Однако в системе, которая выполняет работу, поступающую извне, например веб-сервер, обрабатывающий HTTP-запросы; если вы используете поток для каждого запроса, вы создадите много потоков, многие из них.

-- узел но по-другому? Верно?

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

-- Хм, интересно; но вы можете запускать только одну функцию одновременно, если вы не используете несколько потоков. Как это может работать, когда поступает много запросов веб-сервер в то же время?

-- вы совершенно правы о том, как функции работают, по одному, а не два параллельно. Я имею в виду, что в одном процессе одновременно выполняется только одна область кода. Планировщик ОС не приходит и не приостанавливает эту функцию и не переключается на другую, если только он не приостанавливает процесс, чтобы дать время другому процессу, а не другому потоку в нашем процессе. (2)

-- тогда как процесс может обрабатывать 2 запроса одновременно?

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

-- Хм, я должен быть взволнован?

-- возможно :) узел выполняет цикл над очередью. В этой очереди находятся наши задания, т. е. звонки, которые мы начали обрабатывать входящие запросы. Наиболее важным моментом здесь является то, что мы проектируем наши функции для запуска. Вместо того, чтобы начать обрабатывать запрос и заставлять вызывающего абонента ждать пока мы не закончим работу, мы быстро закончим нашу функцию после выполнения приемлемого объема работы. Когда мы приходим к точке, где нам нужно ждать, пока другой компонент выполнит некоторую работу и вернет нам значение, вместо того, чтобы ждать этого, мы просто заканчиваем нашу функцию, добавляя остальную работу в очередь.

-- это звучит слишком сложно?

-- Нет, Нет, я может показаться сложным, но сама система очень проста и вполне логично.

теперь я хочу остановиться приведу диалог между этими двумя разработчиками и закончу свой ответ после последнего краткого примера того, как работают эти функции.

таким образом, мы делаем то, что обычно делает планировщик ОС. Мы приостанавливаем нашу работу в какой-то момент и позволяем другим вызовам функций (например, другим потокам в многопоточной среде) работать до тех пор, пока мы не получим нашу очередь снова. Это намного лучше, чем оставить работу планировщику ОС, который пытается дать только время каждому потоку в системе. Мы знаем, что мы делаем много лучше, чем планировщик ОС, и мы должны остановиться, когда мы должны остановиться.

Ниже приведен простой пример, где мы открываем файл и читаем его, чтобы сделать некоторую работу над данными.

Синхронно Так:

Open File
Repeat This:    
    Read Some
    Do the work

Асинхронный Образом:

Open File and Do this when it is ready: // Our function returns
    Repeat this:
        Read Some and when it is ready: // Returns again
            Do some work

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

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


(1) Если вы строите библиотек на других языках, таких как C/C++ в этом случае вы все еще не создаете темы для деления рабочих мест. Для такого рода работы у вас есть два потока, один из которых будет поддерживать связь с узлом, а другой делает реальную работу.

(2) фактически, каждый процесс узла имеет несколько потоков по тем же причинам, которые я упомянул в первой сноске. Однако это не похоже на 1000 потоков, выполняющих аналогичные работы. Эти дополнительные потоки предназначены для таких вещей, как принятие событий ввода-вывода и обработка межпроцессного обмена сообщениями.

обновление (как ответ на хороший вопрос в комментариях)

@Марк, спасибо за конструктивную критику. В парадигме Node у вас никогда не должно быть функций, которые занимают слишком много времени для обработки, если все другие вызовы в очереди не предназначены для запуска один за другим. В случае вычислительно дорогих задач, если мы посмотрим на картину полностью, мы увидим, что это не вопрос "Должны ли мы использовать потоки или процессы?"но вопрос "Как мы можем разделить эти задачи хорошо сбалансированным образом на подзадачи, которые мы можем запускать параллельно, используя несколько ядер процессора в системе?"Допустим, мы будем обрабатывать 400 видеофайлов в системе с 8 ядрами. Если мы хотим обрабатывать один файл за раз, то нам нужна система, которая будет обрабатывать разные части одного и того же файла, и в этом случае, возможно, многопоточная однопроцессная система будет проще в построении и даже более эффективной. Мы все еще можем использовать узел для этого, запустив несколько обрабатывает и передает сообщения между ними, когда необходимо совместное использование состояния/связь. Как я уже говорил, многопроцессный подход с узлом-это а также многопоточный подход в такого рода задачах; но не более того. Опять же, как я уже говорил, ситуация, когда узел сияет, когда у нас есть эти задачи, поступающие в систему из нескольких источников, поскольку одновременное сохранение многих соединений намного легче в узле по сравнению с потоком на соединение или система процесс-в-соединения.

как setTimeout(...,0) вызовы; иногда давая перерыв во время трудоемкой задачи, чтобы разрешить Вызовы в очереди имеют свою долю обработки может потребоваться. Разделение задач по-разному может спасти вас от них; но все же, это не совсем хак, это просто способ работы очередей событий. Кроме того, используя process.nextTick для этой цели гораздо лучше, так как при использовании setTimeout, расчет и проверки прошедшего времени будут необходимы в то время как process.nextTick - это просто что мы действительно хотим: "Эй задача, вернитесь в конец очереди, вы использовали свою долю!"

(обновление 2016: веб-работники собираются в io.js-узел.Яш вилка узел.js v7-см. ниже.)

(обновление 2017: веб-работников не идем в узел.js v7 или v8-см. ниже.)

(обновление 2018: Web workers are идем в узел.узел js v10.5.0 - см. ниже.)

уточнение

прочитав ответы выше, я хотел бы отметить, что в web workers нет ничего, что противоречит философии JavaScript в целом и Node в частности в отношении параллелизма. (Если бы это было, это даже не обсуждалось бы WHATWG, а тем более реализовано в браузерах).

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

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

на самом деле веб-работники концептуально идеально подходят для узла, который - как многие люди не знают-кстати использует потоки довольно сильно, и на самом деле" все работает параллельно, кроме вашего кода " - см.:

но веб-работники даже не должны быть реализованы с помощью потоков. Вы можете использовать процессы, зеленые потоки или даже Службы RESTful в облаке - до тех пор, пока используется API web worker. Вся красота передачи сообщений API с помощью вызова семантика значений заключается в том, что базовая реализация в значительной степени не имеет значения, поскольку детали модели параллелизма не будут раскрыты.

однопоточный цикл событий идеально подходит для операций ввода-вывода. Он не работает так хорошо для операций с привязкой к процессору,особенно длительных. Для этого нам нужно создать больше процессов или использовать потоки. Управление дочерними процессами и межпроцессным взаимодействием в переносном режиме может быть довольно сложным, и это часто рассматривается как излишне для простых задач, в то время как использование потоков означает решение проблем блокировки и синхронизации, которые очень трудно сделать правильно.

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

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

узел модули

есть несколько модулей, которые должны добавить веб-работников узла:

Я не использовал ни одного из но у меня есть два быстрых замечания, которые могут быть актуальными: по состоянию на март 2015 года, node-webworker был обновлен 4 года назад, а Node-webworker-threads был обновлен месяц назад. Также я вижу в примере использования node-webworker-threads, что вы можете использовать функцию вместо имени файла в качестве аргумента для рабочего конструктора, который, по-видимому, может вызвать тонкие проблемы, если он реализован с использованием потоков, которые разделяют память (если только функции не используются только для нее .метод toString() и в противном случае компилируется в другой среде, и в этом случае это может быть хорошо - я должен заглянуть в нее более глубоко, просто поделившись своими наблюдениями здесь).

Если есть какой-либо другой соответствующий проект, который реализует Web workers API в узле, пожалуйста, оставьте комментарий.

обновление 1

Я еще не знал этого во время написания, но, кстати, за день до того, как я написал этот ответ веб-работники были добавлены Ио.js.

(io.js является вилкой узла.js-see:почему Ио.js решил разветвить узел.js, интервью InfoWorld с Майклом Роджерсом, для получения дополнительной информации.)

Это не только доказывает, что в веб-работниках нет ничего, что противоречит философии JavaScript в целом и Node в частности в отношении параллелизма, но это может привести к тому, что веб-работники будут первоклассным гражданином в серверном JavaScript, таком как io.в JS (и, возможно, Узел.js в будущем) так же, как это уже есть в клиентском JavaScript во всех современных браузерах.

обновление 2

в Update 1 и мой твиттер я имел в виду io.JS pull request #1159 который теперь перенаправляет на узел PR #1159 это было закрыто 8 июля и заменено на узел PR #2133 - который все еще открыт. В рамках этих запросов на вытягивание, которые могут обеспечить еще немного актуальной информации о статусе веб-работников в io.js / Node.js.

обновление 3

последние новости - спасибо Нику Ньюману за размещение его в комментарии: есть рабочие: начальная реализация совершено Петькой Антоновым от 6 сентября 2015 года это можно скачать и опробовать в дерево. Смотрите комментарии Ника Ньюмана для сведения.

обновление 4

по состоянию на мая 2016 последние комментарии по-прежнему открыт PR #2133-рабочие: первоначальная реализация было 3 месяца. 30 мая Матеус Морейра попросил меня опубликовать обновление этого ответа в комментариях ниже, и он запросил текущее состояние этой функции в комментариях PR.

первые ответы в PR дискуссии были скептическими, но позже Бен Нордхейс писал это " получение этого слияния та или иная форма находится в моем списке задач для v7".

все остальные комментарии, казалось, второй, что и по состоянию на июль 2016 года кажется, что веб-работники должны быть доступны в следующей версии Node, версия 7.0, которая планируется к выпуску на октябрь 2016 (не обязательно в виде этого точного PR).

спасибо Матеусу Морейре за то, что он указал на это в комментариях и оживил обсуждение на GitHub.

обновление 5

по состоянию на июля 2016 есть несколько модулей на npm, которые не были доступны раньше - для полного списка соответствующих модулей, поиск npm для работников, работников паутины, etc. Если что-то в частности делает или не работает для вас, пожалуйста, оставьте комментарий.

обновление 6

по состоянию на январь 2017 маловероятно, что веб-работники будут объединены в узел.js.

запрос на вытягивание #2133 рабочих: первоначальная реализация Петька Антонов с 8 июля 2015 года был наконец закрытые Бен Нордхейс 11 декабря 2016 года, который прокомментировал ,что" многопоточная поддержка добавляет слишком много новых режимов сбоя для недостаточной пользы "и" мы также можем добиться этого, используя более традиционные средства, такие как общая память и более эффективная сериализация."

для получения дополнительной информации см. комментарии к PR 2133 на GitHub.

спасибо снова Матеусу Морейре за то, что он указал на это в комментариях.

обновление 6

Я рад сообщить, что несколько дней назад в июня 2018 веб-работники появились в узле v10.5. 0 в качестве экспериментальной функции, активированной с помощью --experimental-worker флаг.

подробнее:

наконец-то! Я могу сделать 7-е обновление для моего 3-летнего ответа на переполнение стека, где я утверждаю, что потоковые веб-работники a la не против философии узла, только на этот раз говоря, что мы, наконец, получили его!

Я из старой школы мысли, где мы использовали многопоточность, чтобы сделать программное обеспечение быстро. В течение последних 3 лет я использую узел.js и большой сторонник этого. Как хасанясин подробно объяснил, как работает узел и понятие асинхронной функциональности. Но позвольте мне добавить несколько вещей здесь.

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

Так нравится это или нет сигнальный поток или не многоядерный или одноядерный ваши процессы будут вытеснены и время нарезано ОС.

Nodejs представляет собой единый процесс и обеспечивает асинхронный механизм. Здесь задания будут направлены в подстилающем операционной системы для выполнения задач, в то время как мы ждем в цикл событий для задач, чтобы закончить. Как только мы получаем зеленый сигнал от ОС, мы выполняем то, что нам нужно делать. Теперь в некотором смысле это кооперативная / не упреждающая многозадачность, поэтому мы никогда не должны блокировать цикл событий для очень длительный период времени другой мудрый мы будем деградировать наше приложение очень быстро.
Поэтому, если когда-либо есть задача, которая блокируется по своей природе или занимает очень много времени, нам придется разветвлять ее на упреждающий мир ОС и потоков. есть хорошие примеры этого в libuv documentation. Также, если Вы читаете документацию дальше, вы обнаружите, что файлового ввода/вывода обрабатывается в нити в узел.js.

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

под капотом в узел.js его все c++ и потоки. И node предоставляет c++ способ расширить его функциональность и дополнительно ускорить с помощью потоков, где они являются обязательными т. е., блокируя такие задачи, как чтение из источника записи в источник, анализ больших данных и так далее.

Я знаю, что ответ hasanyasin является принятым, но для меня потоки будут существовать независимо от того, что вы говорите или как вы скрываете их за скриптами, во-вторых, никто просто не разбивает вещи на потоки только для скорости, это в основном делается для блокировки задач. И нити находятся в задней кости узла.js поэтому перед тем, как полностью разбить многопоточность, правильно. Также потоки отличаются от процессов, и ограничение наличия узловых процессов на ядро точно не относится к числу потоков, потоки подобны подзадачам для процесса. по сути темы не отображаются в диспетчере задач Windows или топ-команды Linux. еще раз они более мало весят, чем процессы

Я не уверен, что webworkers релевантны в этом случае, они являются клиентскими технологиями (запускаются в браузере), а node.js работает на сервере. Волокна, насколько я понимаю, также блокируются, т. е. они являются добровольными многозадачными, поэтому вы можете их использовать, но должны управлять контекстными переключениями самостоятельно через yield. Потоки могут быть на самом деле то, что вам нужно, но я не знаю, насколько они зрелые в узел.js.

worker_threads был реализован и отправлен за флагом в node@10.5.0. Это все еще первоначальная реализация, и необходимы дополнительные усилия, чтобы сделать ее более эффективной в будущих выпусках. Стоит дать ему попробовать в последней node.

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

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

для работы с асинхронным программированием в коде (например, избегая вложенных пирамид обратного вызова), компонент [Future] в волокнами библиотека-достойный выбор. Я также предлагаю вам проверить Asyncblock который основан на волокнах. Волокна хороши, потому что они позволяют скрыть обратный вызов дублирование стека, а затем прыгать между стеками на одном потоке, как они необходимы. Экономит вам хлопот реальных потоков, давая вам преимущества. Недостатком является то, что следы стека могут быть немного странными при использовании волокон, но они не слишком плохи.

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

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

теперь, сказав Все это, я проделал большую работу с Hook.io в последнее время, который, кажется, работает очень хорошо для такого рода задач разгрузки в другие процессы, возможно, он может выполнить то, что вам нужно.