返回太多数据时Koa服务器崩溃

时间:2017-04-07 08:04:41

标签: node.js mongodb koa

我开发了一个带Koa的轻型节点Web服务器。我包含三个从mongo数据库中检索数据的服务,然后将它们返回给客户端。

返回的对象是一个JSON对象数组。它可以包含大约750.000个对象。 一个对象如下所示:

{"_id":"58a4779b783dbfa853a93e09","attributes":[{"key":"nb_mots","value":"16"},{"key":"fonction","value":"président"},{"key":"groupe_acronyme","value":"UMP"}],"datatype":"deputes","date":"2007-10-23T00:00:00.000Z","eventtype":"loi","actor":"Bernard Accoyer"}

我的服务器在Linux下运行(Debian,我猜......)。

我的问题是:当我想要检索整个数据集时(所以750.000对象 - 使用" allevents"服务如下所示),我的服务器失败了。我得到的唯一信息是" Killed"。我使用命令" top"来调查服务器的状态。当然,%CPU变高(在90和95之间),%MEM也是如此,但没有任何关键(如果我尝试检索更少的数据,那么也是如此)。

有什么想法解决这个问题吗?

我的服务器代码:

var kr = require('koa-route');
var koa = require('koa');
var app = koa();
var _ = require('lodash');

var MongoClient = require("mongodb").MongoClient;

var someeventsPromise = function(datatype, number){
  return new Promise(function(resolve, reject){
        MongoClient.connect("mongodb://localhost/eventdata", function(error, db) {
        if (error){ 
           return reject(error);
        }
        console.log("Connecté à la base de données");

        db.collection('events').find({'datatype' : datatype},{"limit": number ? number : 1000}).toArray(function(err, array)
        {
            console.log('returning %d objects', array.length);
            db.close();
            return resolve({eventsArray : array});
        });
    });
  });
}
var someevents = function * (datatype, number)
{
    var event = yield someeventsPromise(datatype, parseInt(number));
    this.body = event;
}

var alleventsPromise = function(datatype){
  return new Promise(function(resolve, reject){
        MongoClient.connect("mongodb://localhost/eventdata", function(error, db) {
        if (error){ 
           return reject(error);
        }
        console.log("Connecté à la base de données");

        db.collection('events').find({'datatype' : datatype}).toArray(function(err, array)
        {
            console.log('returning %d objects', array.length);
            db.close();
            return resolve({eventsArray : array});
        });
    });
  });
}
var allevents = function * (datatype)
{
    var event = yield alleventsPromise(datatype);
    this.body = event;
}

var minmaxdatesPromise = function (datatype)
{
  return new Promise(function(resolve, reject){
        MongoClient.connect("mongodb://localhost/eventdata", function(error, db) {
        if (error){ 
           return reject(error);
        }
        console.log("Connecté à la base de données");

        db.collection('events').find({'datatype' : datatype}, {date : 1}).toArray(function(err, array)
        {
            console.log('returning %d objects', array.length);
            db.close();

            let g = _.map(_.uniqBy(array, function(d) {return d.date}), function(d) { return new Date(d.date);});
            console.log('mapping to %d objects', g.length);

            g.sort(function(a,b) { return b - a ; });

            let minmax = { maxdate : g[0], mindate : g[g.length - 1]};
            return resolve(minmax);
        });
    });
  });
}

var minmaxdates = function * (datatype)
{
    var dates = yield minmaxdatesPromise(datatype)
    this.body = dates;
}


app.use(kr.get('/someevents/:datatype/:number', someevents));
app.use(kr.get('/allevents/:datatype', allevents));
app.use(kr.get('/minmaxdates/:datatype', minmaxdates));

app.listen(3010);

1 个答案:

答案 0 :(得分:0)

由于我非常确定我的问题与我需要检索许多数据这一事实有关,因此我尝试通过流发送它们(而不是将它们存储在一个大数组中)。

没有运气,我还有另外一个问题:

  

错误:写EPIPE        at exports._errnoException(util.js:1023:11)        在WriteWrap.afterWrite [as oncomplete](net.js:804:14)

我的代码如下:

var kr = require('koa-route');
var koa = require('koa');
var app = koa();
var _ = require('lodash');

var MongoClient = require('mongodb').MongoClient;


var allevents = function * (datatype)
{

  var ctx = this;

  var db = yield MongoClient.connect('mongodb://localhost/eventdata');
  console.log("Querying all data for " + datatype);

  // Get the collection
  var col = db.collection('events');

  ctx.body = col.find({'datatype' : datatype}).stream(
  { 
      transform: function(doc) { 
        return JSON.stringify(doc);
      }
  });
}

app.use(kr.get('/allevents/:datatype', allevents));

app.listen(3010);

最后的事情:所有结果都在C#Unity脚本中使用(以防万一)。

提前致谢。

BTW:我无法检索到更少的数据,我需要所有数据。