Node.js 在Nodejs/Request/MongoDB中调用过多承诺时内存泄漏
当我试图在NodeJS中调用多达200000个POST请求时,它显示了一些错误,比如堆内存泄漏 在每个POST请求中,我希望将解析后的数据插入localhost mongo DB 一次发出2000个请求是可以的,但是处理200000个请求确实很困难。 我陷入了这个问题,不知道该怎么解决 我真的需要你的帮助或任何建议 提前感谢您的帮助Node.js 在Nodejs/Request/MongoDB中调用过多承诺时内存泄漏,node.js,mongodb,mongoose,memory-leaks,request,Node.js,Mongodb,Mongoose,Memory Leaks,Request,当我试图在NodeJS中调用多达200000个POST请求时,它显示了一些错误,比如堆内存泄漏 在每个POST请求中,我希望将解析后的数据插入localhost mongo DB 一次发出2000个请求是可以的,但是处理200000个请求确实很困难。 我陷入了这个问题,不知道该怎么解决 我真的需要你的帮助或任何建议 提前感谢您的帮助 const mongoose=require('mongoose'); const request=require('request'); //数据库连接 猫鼬 .
const mongoose=require('mongoose');
const request=require('request');
//数据库连接
猫鼬
.连接(“mongodb://localhost:27017/test?retryWrites=true&w=majority“,{useNewUrlParser:true,useUnifiedTopology:true})
。然后(()=>console.log('Connected!'))
.catch(err=>console.error('无法连接…',err));
//初始化Mongoose的模型
const Sample=mongoose.model(
“样本”,
新的mongoose.Schema({},{strict:false,versionKey:false}),
“样本收集”
);
//将数据插入示例
var insertDataIntoSample=函数(平均值){
Sample.collection.insert(表示,{ordered:false});
}
//获取数据的HTTP POST请求
const getDataFromInternet=函数(参数){
返回新承诺((解决、拒绝)=>{
请寄(
'https://url-to-post-data.com/',
{json:{'query':param},
功能(错误、响应、正文){
如果(!error&&response.statusCode==200&&body){
将数据插入示例(body.data);
决心(param);
}
}
);
});
};
//呼叫多达200000个请求
var myParams=[…]//200000个元素
对于(变量i=0;i
因此,一次向数据库提交200000个请求只会适得其反。无论如何,您的数据库不可能一次处理多个请求,因此您同时处理多个请求所做的一切只会导致大量的峰值内存使用
通过一些测试,您将了解大约有多少同时请求仍然有效,这完全取决于您的数据库及其配置。一个大型的iron数据库服务器,可以访问大量的CPU/线程,甚至可以访问一些有效的磁盘分区,并且一次可以在许多请求上取得进展。一次只运行几个请求之后,较小的配置可能不会获得任何好处
在stackoverflow和其他地方有几十个选项,可以在处理数组时进行异步函数调用,这样在同一时间只有N个请求在运行。这可能是你想要的一般概念。诸如Bluebird和Async Promises之类的库具有内置的函数来管理并发访问
我最喜欢的一个简单函数(只是一个可以复制的函数)叫做mapConcurrent()
。您向它传递数组、一次要处理的最大请求数以及它将为数组中的每个项调用的承诺返回函数
您使用配置运行实验,以查看maxConcurrent的最佳值是多少(提示,它可能是一个相当小的数字,如10以下)
//接受一个项目数组和一个返回承诺的函数
函数mapConcurrent(项,maxConcurrent,fn){
设指数=0;
设inFlightCntr=0;
设doneCntr=0;
让结果=新数组(items.length);
让停止=错误;
返回新承诺(功能(解决、拒绝){
函数runNext(){
设i=指数;
++inFlightCntr;
fn(项目[索引],索引+)。然后(函数(val){
++doneCntr;
--inFlightCntr;
结果[i]=val;
run();
},函数(err){
//设置标志,这样我们就不会再启动任何请求
停止=真;
拒绝(错误);
});
}
函数运行(){
//我们可以发射多少就发射多少
而(!stop&&inflightCntr
此答案中还提到了一些其他选项。200k请求是否同时全部出现?我不会那么做的。使用类似
// takes an array of items and a function that returns a promise
function mapConcurrent(items, maxConcurrent, fn) {
let index = 0;
let inFlightCntr = 0;
let doneCntr = 0;
let results = new Array(items.length);
let stop = false;
return new Promise(function(resolve, reject) {
function runNext() {
let i = index;
++inFlightCntr;
fn(items[index], index++).then(function(val) {
++doneCntr;
--inFlightCntr;
results[i] = val;
run();
}, function(err) {
// set flag so we don't launch any more requests
stop = true;
reject(err);
});
}
function run() {
// launch as many as we're allowed to
while (!stop && inflightCntr < maxConcurrent && index < items.length) {
runNext();
}
// if all are done, then resolve parent promise with results
if (doneCntr === items.length) {
resolve(results);
}
}
run();
});
}