Node.js 如何一次发出40万个请求200个?
我有大量的请求,我需要同时运行200到600个以上的请求,但不能超过这个数量。目前我正在同时发送400k请求,但这占用了我的堆内存,然后跳到堆上——也就是说,它使用了我没有的数百GB内存 我目前正在使用类似于此的循环来处理请求:Node.js 如何一次发出40万个请求200个?,node.js,mongodb,memory-leaks,axios,out-of-memory,Node.js,Mongodb,Memory Leaks,Axios,Out Of Memory,我有大量的请求,我需要同时运行200到600个以上的请求,但不能超过这个数量。目前我正在同时发送400k请求,但这占用了我的堆内存,然后跳到堆上——也就是说,它使用了我没有的数百GB内存 我目前正在使用类似于此的循环来处理请求: ["url1", "url2", ...].forEach(async item => { Axios(config) .then(res => DO STUFF) .catch(err => console.l
["url1", "url2", ...].forEach(async item => {
Axios(config)
.then(res => DO STUFF)
.catch(err => console.log(err);
await DO_MORE STUFF
});
链接实际上存储在MongoDB集合中,我使用的是Cursor.forEach。在异步函数中,需要使用wait for stop循环,直到执行操作为止。 您确实这样做了,但循环还返回了一个承诺数组,您需要解析该数组以获得正确的结果
const urls = ["url1", "url2", ...]
const allPromise = urls.map(async item => {
try {
const res = await Axios(config)
await DO_MORE STUFF
} catch(error) {
console.log({ error })
}
});
await Promise.all(allPromise)
如果外部函数不是异步函数,那么您可以使用
。然后,因此您必须将阵列切片为更小的阵列,并使用爬升超时循环每个切片
let urls = ["url1", "url2", ...];
let reqPerTime = 400;
let rampUp = 0 ;
function loopRecursively (from ) {
if ( from > urls.length ) { return ;}
let arr = urls.slice(from, from + reqPerTime );
arr.forEach(async item => {
Axios(config)
.then(res => DO STUFF)
.catch(err => console.log(err);
await DO_MORE STUFF
});
rampUp = rampUp + 500;
setTimeout ( () => { loopRecursively( from + reqPerTime ) }, rampUp );
}
loopRecursively(0);
您可以使用游标的nextObject
功能
下面是一个使用它的解决方案(未经测试,可能存在语法错误)
这样,您将有200个axios请求的批处理。完成所有200个axios查询后,开始构建下一批
let axiosConfigs = [];
async function runAxios() {
// Do your axios stuff here on axiosConfigs
// Here is an example :
await Promise.all(axiosConfigs.map((config) => {
return Axios(config);
}))
// Once finished, clear the axiosConfigs array
axiosConfigs = [];
}
function createAxiosConfig(urlRecord) {
// return here the axios config for this url record
}
const cursor = db.collection("urls").find({});
while(await cursor.hasNext()) {
const urlRecord= await cursor.next();
axiosConfigs.push(createAxiosConfig(urlRecord));
if(axiosConfigs.length === 200) {
await runAllAxioses()
}
}