2017-04-07 12 views
0

私はKoaを使って軽いノードのWebサーバを開発しました。私は、mongoデータベースからデータを取り出し、それをクライアントに返す3つのサービスを含んでいます。あまりにも多くのデータを返すと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#ユニティスクリプトで使用されています。

ありがとうございます。

ところで、データを取得することはできません。そのすべてが必要です。

関連する問題