В контексте Nodejs, почему фраза «Не блокировать событие L oop» существует даже в разработке, ее нельзя избежать? - PullRequest
0 голосов
/ 02 мая 2020

Представьте себе простое express веб-приложение, как показано ниже.

const express = require('express')                                                                                                                                                                                                                                                                                                                 

const app = express()                                                                                                                                                                                                                                                                                                                              
const port = 3000                                                                                                                                                                                                                                                                                                                                  

app.get('/', (req, res) => {
  takeTimePlain()                                                                                                                                                                                                                                                                                                          
  res.send('Hello World!')                                                                                                                                                                                                                                                                                                                         
})  

app.listen(port, () => {                                                                                                                                                                                                                                                                                                                           
  console.log(`Example app listening at http://localhost:${port}`)                                                                                                                                                                                                                                                                                 
})  

function takeTimePlain () {                                                                                                                                                                                                                                                                                                                     
  /* Long Job Operation Simulation */                                                                                                                                                                                                                                                                                                              

  let date = Date.now();                                                                                                                                                                                                                                                                                                                           
  let end = Date.now() + 5000;                                                                                                                                                                                                                                                                                                                     

  while (date < end ) {                                                                                                                                                                                                                                                                                                                            
    console.log ("Iterating through while loop")                                                                                                                                                                                                                                                                                                   
    date = Date.now()                                                                                                                                                                                                                                                                                                                              
  }                                                                                                                                                                                                                                                                                                                                                
  return                                                                                                                                                                                                                                                                                                                                           
} 

Тогда я звоню http://localhost:3000 3 раза одновременно. Если я проверяю задержку или время ожидания сервера,

  • Если задержка для первого запроса равна x
  • , то для второго запроса требуется 2x время
  • и для третьего запроса требуется 3x время для завершения

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

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

Есть ли неблокирующая альтернатива takeTimePlain()? Я знаю о setTimeout(cb, 5000), однако я не собираюсь ждать 5 секунд. Это takeTimePlain() может быть что угодно, как сортировка и массив, упорядочение, поиск и т. Д. c. Это распространенное решение для кодирования, позволяющее реплицировать процесс, который требует времени процессора.

Редактировать: Этот вопрос не о скептицизме или предложениях. Речь идет о разъяснении фактов после показа реальных ориентиров. Не стесняйтесь редактировать заголовок, если он не соответствует содержанию.

1 Ответ

1 голос
/ 02 мая 2020

В этом ответе есть несколько частей.

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

Но если это произойдет, есть несколько вариантов:

A) запустить другой процесс для запуска длинного кода блокировки.

B) использовать cluster.

Кластер позволит вам открыть столько процессов узла https, сколько вам нужно на одном и том же порту. https://nodejs.org/api/cluster.html Существует множество решений, подобных кластеру, но кластер - это его сборка.

Для исправления takeTimePlain вы могли бы вместо всех oop использовать setInterval со временем 0. Затем очистите его, как только вы дойдете до конца. Хотя это будет очень медленно.

Последний узел / express не более масштабируем, чем любое другое решение.

...