Как сервер node.js обслуживает следующий запрос, если текущий запрос требует больших вычислений?

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

Есть ли какое-либо другое решение, которое мы можем сделать с node.js, чтобы не ждать других запросов на их очередь так долго?

2 ответа

Как сервер node.js обслуживает следующий запрос, если текущий запрос требует больших вычислений?

Это не так - если это вычисление происходит в главном потоке и не разделено на более мелкие части.

Чтобы иметь возможность обслуживать другой запрос во время задачи, интенсивно использующей процессор, вам необходимо:

  1. разбить ваши вычисления на части и использовать setImmediate или process.nextTick для их запуска
  2. используйте для этой задачи внешний процесс и вызывайте его, как любую другую внешнюю программу или службу, используя HTTP, TCP, IPC или порождение дочернего процесса, или используя систему очередей, pub/sub и т. д.
  3. написать нативную надстройку на C++ и использовать темы для этого

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

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

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

И для этого у узла есть решение:

https://nodejs.org/api/cluster.html

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

Другие вопросы по тегам