Задать вопрос

Как сделать многопоточный HTTP(S) сервер в ноде?

На ноде мне требуется написать веб сервер, который при открытии по адресу 127.0.0.1:8080 будет в фоновом режиме таскать файлы через wget и отдавать.

Вот простой пример сервера

var http = require('http');
http.createServer(function (req, res) {
//тут 60 секунд идет работа в СИНХРОННОМ режиме через wget и подобные
//fs.readFileSync
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write(req.url);
    res.end();
}).listen(8080);


Открываю 2 разных браузера
В каждый вбиваю 127.0.0.1:8080 и нажимаю одновременно Ентер
И опа!
Один браузер работает, потом как первый заканчивает работу начинает работать второй.
Нет многопоточности т.е. второй ждет пока первый закончит работу.
Я такого не ожидал от ноды.
В чем проблема? и как протестировать на асинхронность веб сервер и как сделать так чтобы по этому адресу 127.0.0.1:8080 можно было конектится в 100 потоков?

От fs.readFileSync никак не избавиться
  • Вопрос задан
  • 1569 просмотров
Подписаться 7 Средний 1 комментарий
Решения вопроса 2
DevMan
@DevMan
нода никогда и не была многопоточной из коробки.
Долгая операция (конвертация картинки) блокирует сервер, что делать?
Ответ написан
Комментировать
@grinat
var cluster = require('cluster');
var http = require('http');
var numCPUs = 100;

if (cluster.isMaster) {
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
} else {
    console.log('created ' + process.pid)
    http.createServer(function(req, res) {
        res.writeHead(200);
        res.end('process ' + process.pid + ' says hello!');
    }).listen(8000);
}

Ну или так:
npm install pm2@latest -g
pm2 start app.js -i 100
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
samodum
@samodum
Какой вопрос - такой и ответ
Надо ноду менять на Go
Ответ написан
Deissh
@Deissh
I like Python, Node.JS, Go, pain, bugs and my cat.
Нет таких ситуаций когда от fs.readFileSync не избавиться, проблема уже в разработчике, который пытается избавиться.
Вся ваша проблема в синхронном fs.readFileSync.
Ответ написан
Комментировать
@ofigenn
Из кода непонятно в чём проблема. Само по себе синхронное чтение файла блокирует поток только на время чтения. Файлы большого размера? сколько памяти на сервере?
А вот отправка буфера, будет идти асинхронно. И в этом случае странно, что второй запрос, выполняется строго после первого.
Идеально, конечно использовать fs.createReadStream. Тогда проблем не будет ни с памятью ни с блокировками.
Ответ написан
Комментировать
@Gaito
Конечно всё правильно, что нечего использовать синхронные операции, такие как fs.readFileSync, и обычно вручную поднимать несколько потоков в ноде мало кому нужно, но это не значит, что такой возможности нет совсем, как об этом пишут во многих источниках.

Для организации многопоточного приложения в ноде есть child_process https://nodejs.org/api/child_process.html

Но например решить проблему с конкурентным доступом к большим файлам сам по себе он не поможет и придётся сильно попотеть для этого. Подобное интересно сделать в академических целях, но на практике куда проще, быстрее и дешевле масштабировать сервис, поднимая несколько его инстансов и распределяя трафик по ним при помощи балансировщика.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы