2017-04-07 95 views
0

我開發了一個Koa的輕型節點Web服務器。我包含三個從mongo數據庫檢索數據的服務,然後將它們返回給客戶端。Koa服務器在返回太多數據時崩潰

返回的對象是一個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); 
+0

也許不這樣做!? –

+0

我的猜測是,您的內存不足,您的計算機將終止進程。嘗試減少10個記錄的數量,並檢查一切是否正確與您的代碼,然後嘗試並找出如何消耗更少的內存,儘管我認爲你不能,因爲記錄數量太多。 –

+0

完全正確:當我減少數據量時它不會失敗,但有時我需要全部獲取它們。我被建議使用流和管道。 – MrFlo

回答

0

正如我敢肯定,我的問題是有關的事實,我有很多的數據檢索,我試圖通過流送他們(而不是將它們存儲在一個大陣列中)。

沒有運氣,我還有一個問題,那麼:

Error: write EPIPE at 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#團結腳本(以防萬一)使用。

在此先感謝。

順便說一句:我無法檢索更少的數據,我需要所有這些數據。