Почему Node.js однопоточный?

В веб-серверах на основе PHP (или Java/ASP.NET/Ruby) каждый клиентский запрос создается в новом потоке. Но в Node.js все клиенты работают в одном потоке (они могут даже использовать одни и те же переменные!) Я понимаю, что операции ввода-вывода основаны на событиях, поэтому они не блокируют цикл основного потока.

Я не понимаю, почему автор Node выбрал однопоточное? Это усложняет ситуацию. Например, я не могу запускать интенсивную работу с ЦП, поскольку он блокирует основной поток (и новые клиентские запросы блокируются), поэтому мне нужно создать процесс (что означает, что мне нужно создать отдельный файл JavaScript и выполнить другой процесс Node в теме). Однако в PHP cpu интенсивные задачи не блокируют других клиентов, потому что, поскольку я упоминал, что каждый клиент находится в другом потоке. Каковы его преимущества по сравнению с многопоточными веб-серверами?

Примечание. Я использовал кластеризацию, чтобы обойти это, но это не очень.

Ответ 1

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

И знаешь что? По-моему, теория была подтверждена. Приложение node.js, которое не выполняет интенсивные работы с ЦП, может выполнять тысячи одновременных подключений, чем Apache или IIS или другие серверы на основе потоков.

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

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

Ответ 2

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

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

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

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

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

Ответ 3

Короче говоря, node извлекает из V8, который является внутренне однопоточным. Есть способы обойти ограничения для задач с интенсивным использованием ЦП.

В какой-то момент (0.7) авторы попытались ввести изоляты как способ реализации нескольких потоков вычислений, но в конечном итоге были удалены: https://groups.google.com/forum/#!msg/nodejs/zLzuo292hX0/F7gqfUiKi2sJ