Что происходит, когда один и тот же запрос занимает много времени на этих неблокирующих серверах ввода-вывода? - PullRequest
7 голосов
/ 17 ноября 2011

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

Например, поступает запрос, и для его вычисления требуется 200 мс, это блокирует другие запросы, например, nodejs использует один поток.

Это означает, что ваши 15K в секунду существенно снизятся из-за фактического времени, которое требуется для вычисления ответа на данный запрос.

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

Ответы [ 6 ]

7 голосов
/ 17 ноября 2011

Зависит ли это от "блоков", зависит от вашего определения "блока". Обычно блокировка означает, что ваш ЦП практически не используется, но текущий поток не может ничего с ним сделать, потому что он ожидает ввода-вывода или тому подобное. Подобного не случается в node.js, если вы не используете нерекомендованные функции синхронного ввода-вывода. Вместо этого функции быстро возвращаются, и когда задача ввода-вывода началась, ваш обратный вызов вызывается, и вы берете его оттуда. Тем временем могут быть обработаны другие запросы.

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

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

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

1 голос
/ 17 ноября 2011

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

Другими словами :

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

1 голос
/ 17 ноября 2011

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

Редактировать: рабочие - это процессы.

1 голос
/ 17 ноября 2011

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

На большинстве современных платформ node.js делает США темы для ввода / вывода.Он использует libev, который использует потоки там, где лучше всего работает на платформе.

1 голос
/ 17 ноября 2011

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

Все, что займет «много времени», должно выполняться асинхронно.

0 голосов
/ 08 июня 2018

Вот некоторый код, чтобы увидеть блокировку / неблокировку в действии:

  • В этом примере (длинная задача ЦП, без ввода-вывода):

    var net = require('net');
    handler = function(req, res) {
        console.log('hello');
        for (i = 0; i < 10000000000; i++) { a = i + 5;  }
    }
    net.createServer(handler).listen(80);
    

    если вы делаете 2 запроса в браузере, в консоли сервера будет отображаться только один hello, что означает, что второй запрос не может быть обработан, поскольку первый блокирует поток Node.js .

  • Если вместо этого мы выполним задачу ввода-вывода (запишите 2 ГБ данных на диск, это заняло несколько секунд во время моего теста, даже на SSD):

    http = require('http');
    fs = require('fs');
    buffer = Buffer.alloc(2*1000*1000*1000);
    first = true;
    done = false;
    
    write = function() {
        fs.writeFile('big.bin', buffer, function() { done = true; });
    }
    
    handler = function(req, res) {
        if (first) {
            first = false;
            res.end('Starting write..')
            write();      
            return;
        }
        if (done) { 
            res.end("write done."); 
        } else {  
            res.end('writing ongoing.'); 
        }
    }
    
    http.createServer(handler).listen(80);
    

    здесь мы видим, что задача записи в несколько длинных секунд ввода-вывода write не блокирует : если вы в это время делаете другие запросы, вы увидите writing ongoing.! Это подтверждает хорошо известные неблокирующие для ввода-вывода функции Node.js .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...