Как мне избежать блокировки express службы отдыха? - PullRequest
0 голосов
/ 08 апреля 2020

При создании службы REST с использованием express в узле, как я могу предотвратить задачу блокировки от блокировки всей службы покоя? Возьмем в качестве примера следующую express службу отдыха:

const express = require('express');
const app = express();

app.get('/', (req, res) => res.send('Hello, World'));

const blockService = async function () {
    return new Promise((resolve, reject) => {
        const end = Date.now() + 20000;
        while (Date.now() < end) {
            const doSomethingHeavyInJavaScript = 1 + 2 + 3;
        }
        resolve('I am done');
    });
}

const blockController = function (req, res) {
    blockService().then((val) => {
        res.send(val);
    });
};

app.get('/block', blockController);

app.listen(3000, () => console.log('app listening on port 3000'));

В этом случае вызов / block сделает весь сервис недоступным в течение 20 секунд. Это большая проблема, если есть много клиентов, использующих сервис, поскольку ни один другой клиент не сможет получить доступ к сервису в течение этого времени. Это, очевидно, проблема того, что в то время как l oop блокирует код и, таким образом, вешает основной поток. Этот код может сбивать с толку, поскольку, несмотря на использование обещания в blockService, основной поток все еще зависает. Как мне убедиться, что blockService будет запускать рабочий поток, а не событие-l oop?

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

По умолчанию node.js запускает ваш код Javascript в одном потоке. Так что, если у вас действительно есть процессороемкий код в обработчике запросов (как показано выше), то это действительно проблема. Возможны следующие варианты:

  1. Запустить рабочий поток и запустить код с интенсивным использованием процессора в рабочем потоке. Начиная с версии 10, node.js имеет рабочие потоки для этой цели. Затем вы возвращаете результат в основной поток с помощью обмена сообщениями.

  2. Запустите любой другой процесс, который выполняет код node.js или любой тип кода, и вычислите результат в этом другом процессе. Затем вы возвращаете результат в основной поток с помощью обмена сообщениями.

  3. Используйте кластеризацию узлов для запуска N процессов, чтобы, если один раз процесс застрял с интенсивной работой ЦП, по крайней мере, один из другие, мы надеемся, могут свободно выполнять другие запросы.

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

0 голосов
/ 08 апреля 2020

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

рабочие потоки были выпущены в Node.js v12. Это позволяет использовать другой поток для блокировки задач. Они относительно просты в использовании и могут работать, если вам абсолютно необходимы задачи блокировки разгрузки.

...