2014-01-21 23 views
6

У меня есть следующий фрагмент кодаExpressJS - Как обрабатывать одновременные запросы? Запросы, похоже, блокируют друг друга.

var express = require('express'); 
var routes = require('./routes');  
var http = require('http'); 
... 
app.get('/a',function(){ 
    Card.findCards(function(err, result){ //Mongoose schema 
    res.send(result); //Executes a query with 9000 records 
    }) 
}); 
app.get('/b', function(req, res){ 
    res.send("Hello World"); 
}); 

Я считаю, что, когда я делаю получить на локальном хосте/а, она занимает около 2,3 секунд. Это не удивительно, так как он извлекает из базы данных довольно много данных. Однако я обнаружил, что если I GET/b во время загрузки/b, b не будет отображаться. Это как если бы вызов/a блокировал вызов в/b.

Это как работает экспресс? Я всегда работал на предположениях, что отдельные маршруты являются асинхронными, поскольку они принимают обратные вызовы, но кажется, что экспресс может обрабатывать только один запрос за раз. До вызова res.end() никакой другой запрос не обрабатывается. Мне не хватает какой-либо конфигурации, которую мне нужно сделать?

Для справки, это, как я подключиться к мангуст

mongoose.connect(dbConnectionString, {server:{poolSize:25}}); 

И это мой HTTP сервер инициализации часть

http.globalAent.maxSockets = 20; // or whatever 

http.createServer(app).listen(app.get('port'), function(){ 
    console.log('Express server listening on port ' + app.get('port')); 
}); 

EDIT: Вот код для модели карты и связанные с ними схемы + функции

//Card.js 
var mongoose = require('mongoose') 
    , Schema = mongoose.Schema; 

var CardSchema = new Schema({ 
    _id : {type: String}, 
    stores : [{ 
     store: {type: Schema.Types.ObjectId, ref:'StoreModel', required: true} 
     , points: {type: Number, required: true} 
    }] 
}); 

exports.findCards = function(callback){ 
    var query = Card.find({}, callback); 
} 

ответ

0

попробую :)

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

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

+0

Так мангуст дБ звонки блокируются? Я всегда думал, что вызовы db - например, входные - не блокируют, следовательно, используют обратные вызовы. – pauloadaoag

+0

Звонки на звонки в формате Moongoose не блокируются в том смысле, что ваше приложение не блокируется ожиданием ответа mongo, но вашему приложению по-прежнему необходимо буферизовать и обрабатывать несколько тысяч записей после их поступления из монго, и это занимает циклы процессора в реактор – bbozo

+0

Это может быть правдой, но я сделал тест, в котором я вызвал res.send («hello world») перед тем, как процессор потребляет вызов мангуста. Даже заменил вызов мангуста простым просыпанием, и то же самое произошло. Экспресс все еще обрабатывал запросы даже во время вызова мангуста. Поэтому мой вывод состоит в том, что только один объект request/response может обрабатываться экспресс в любой момент времени. 'app.get ('/ a', function() {' 'console.log (" a ");' 'res.send (" a ");' 'Card.findCards (function (err, result) {' ' console.log ("done"); ' '}) ' '}); ' – pauloadaoag

2

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

Первая проблема заключается в вызове мангуста. После того, как мангуста извлекает документы из вашей коллекции, он преобразует их в объекты мангуста. Если вы получите 9000 записей, он будет делать это 9000 раз. Линии, о которых идет речь, находятся в библиотеке query.js mongoose; проверьте цикл for на своей функции completeMany, чтобы найти соответствующие операции блокировки.

Вторая проблема возникает, когда Express строит результирующие объекты JSON для отправки вашего ответа. Преступником является функция res.json в библиотеке Экспресс response.js. Для большого ответа будет заметным блокирующий характер stringify.

Я не совсем уверен, как решить эту проблему. Вероятно, вы могли бы попытаться использовать собственную библиотеку mongodb, а не mongoose. Вы также можете попробовать установить патч Express, чтобы он использовал потоковые вызовы JSON вместо блокировки. Разметка вашего запроса и ответа также поможет, хотя я знаю, что это не очень просто реализовать.

+0

Я согласен с вышесказанным. Кажется, что OP делает правильный код материала, за исключением вытягивания 9k записей, а затем сериализуется в JSON и отправляет 9k записей на провод. Это никогда не будет уменьшаться независимо от того, как вы на это смотрите. Paginate, чтобы вы всегда могли контролировать время отклика. – Biba

0

Вы можете установить опцию lean.

Документы, возвращенные из запросов с включенным опцией lean, представляют собой простые объекты javascript, а не MongooseDocuments. У них нет метода сохранения, геттеров/сеттеров или другой магии Мангуста.

Пример:

new Query().lean() // true 
new Query().lean(true) 
new Query().lean(false) 

Model.find().lean().exec(function (err, docs) { 
    docs[0] instanceof mongoose.Document // false 
}); 

см mongoose documentation

Смежные вопросы