【问题标题】:How do I make 400k requests 200 at a time?如何一次发出 40 万个请求 200 个?
【发布时间】:2020-01-04 07:10:12
【问题描述】:

我有大量请求,我需要同时运行或多或少 200 到 600 个上述请求,但不要超过这个数量。目前我正在同时发送 400k 个请求,但这会占用我的堆内存,然后跳转到它上面——也就是说它使用了数 GB 的内存,而我没有。

我目前正在使用与此类似的循环来处理请求:

["url1", "url2", ...].forEach(async item => {
    Axios(config)
        .then(res => DO STUFF)
        .catch(err => console.log(err);
    await DO_MORE STUFF
});

链接实际上存储在 MongoDB 集合中,我使用的是 Cursor.forEach。

【问题讨论】:

    标签: node.js mongodb memory-leaks axios out-of-memory


    【解决方案1】:

    在异步函数中,您需要使用等待停止循环,直到执行操作。 你已经做了,但循环也返回了你需要解决以获得正确结果的承诺数组

    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)
    

    如果外部函数不是异步函数,那么你可以使用.then

    【讨论】:

      【解决方案2】:

      所以你必须将你的数组分割成更小的数组,并为每个切片循环,并增加超时时间。

       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);
      

      【讨论】:

        【解决方案3】:

        您可以使用光标的nextObject功能。

        这是一个使用它的解决方案(未经测试,可能存在语法错误)

        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()
          }
        }
        

        这样,您将拥有 200 个批量的 axios 请求。一旦所有 200 个 axios 查询都结束后,就开始构建下一批

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多