Подтвердить что ты не робот

Понимание NodeJS & Non-Blocking IO

Итак, мне недавно был добавлен вирус Node, который очень быстро распространяется в мире программирования.

Я очарован этим "Неблокирующимся IO" и действительно попробовал пару программ самостоятельно.

Тем не менее, я не понимаю некоторых концепций на данный момент.

Мне нужны ответы в условиях неспециалиста (кто-то из фона Java)

1. Многопоточность и неблокирование IO.

Рассмотрим практический сценарий. Скажем, у нас есть сайт, на котором пользователи могут зарегистрироваться. Ниже будет код.

..
..
   // Read HTTP Parameters
   // Do some Database work
   // Do some file work
   // Return a confirmation message
..
..

В традиционном языке программирования вышеуказанное происходит последовательно. И, если есть несколько запросов на регистрацию, веб-сервер создает новый поток, а остальная часть - история. Конечно, программисты могут создавать собственные потоки для работы в Line 2 и Line 3 одновременно.

В Node, как я понимаю, строки 2 и 3 будут выполняться параллельно, в то время как остальная часть программы будет выполнена, а интерпретатор проверяет строки 2 и 3 каждые "х" мс.

Теперь, на мой вопрос, если Node - это один поток, то что делает работа строк 2 и 3 в то время как остальная часть программы выполняется?

2. Масштабируемость

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

Может кто-нибудь объяснить, как это повлияло?

3. Адаптация в других языках программирования

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

Я уверен, что я что-то упустил. Только если вы сможете объяснить мне и направить мне некоторые ссылки, было бы полезно.

Спасибо.

4b9b3361

Ответ 1

Был задан аналогичный вопрос и, вероятно, содержит всю информацию, которую вы ищете: Как работает однопоточная неблокирующая IO-модель в Node.js

Но я кратко расскажу о ваших трех частях:

1.
Строки 2 и 3 в очень простой форме могут выглядеть так:
    db.query(..., function (query_data) {...});       fbsreadFile ('/path/to/file', function (file_data) {...});

Теперь функцией (query_data) и функцией (file_data) являются обратные вызовы. Функции db.query и fs.readFile отправят фактические запросы ввода-вывода, но обратные вызовы позволяют обрабатывать данные из базы данных или файла, которые будут отложены до получения ответов. Это действительно не "линии опроса 2 и 3". Обратные вызовы добавляются в цикл событий и связаны с некоторыми файловыми дескрипторами для соответствующих событий ввода-вывода. Затем он обследует дескрипторы файлов, чтобы убедиться, что они готовы выполнить ввод-вывод. Если они есть, он выполняет функции обратного вызова с данными ввода/вывода.

Я думаю, что фраза "Все работает параллельно, кроме вашего кода" суммирует ее хорошо. Например, что-то вроде "Чтение параметров HTTP" будет выполняться последовательно, но функции ввода-вывода, подобные строкам 2 и 3, связаны с обратными вызовами, которые добавляются в цикл событий и выполняются позже. Таким образом, в основном все дело в том, что ему не нужно ждать ввода/вывода.

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

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

Мне может быть немного, но это суть происходящего.

Ответ 2

Q1. "Какова работа линий 2 и 3, пока выполняется остальная часть программы?" Ответ: "Ничего". Строки 2 и 3 сами начинают свои соответствующие задания, но эти задания не могут быть выполнены немедленно, потому что (например) требуемые сектора диска еще не загружены - поэтому операционная система выдает вызов на диск, чтобы получить эти сектора, затем "Ничего не происходит" (node продолжает следующую задачу), пока дисковая подсистема (позже) не выдает прерывание, чтобы сообщить, что они готовы, после чего node возвращает управление строкам # 2 и # 3.

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

Q3. почти каждый язык программирования уже имеет неблокирующий ввод-вывод, если вы хотите его использовать. node не является языком программирования, это веб-сервер, который запускает javascript и использует неблокирующий ввод-вывод (например: я лично написал свою собственную идентичную вещь 10 лет назад в perl, как и google (в C), когда они начали, и я уверен, что у других людей есть похожие веб-серверы). Неблокирующий ввод-вывод не является сложной задачей - заставить программиста понять, как его использовать, это сложный бит. Javascript для этого хорошо работает, потому что эти программисты уже знакомы с программированием событий.

Ответ 3

Несмотря на то, что node.js существует уже несколько лет, эта модель производительности по-прежнему немного загадочна.

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

Блокировка против неблокирующего ввода-вывода - Что происходит?

Понимание node.js Производительность