返回太多数据时 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"服务(时,我的服务器失败了。我收到的唯一消息是"被杀"。我使用命令"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);

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

没有运气,然后我有另一个问题:

错误:写入 EPIPE 在exports._errnoException (util.js:1023:11( at 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脚本(以防万一(。

提前谢谢。

顺便说一句:我无法检索更少的数据,我需要所有这些数据。

最新更新