2017-11-15 9 views
0

크롤러 작업 중. URL 목록을 요청해야합니다. 비동기로 설정하지 않으면 여러 번 요청이 동시에 발생합니다. 나는 그것이 내 대역폭을 폭발 시키거나 타겟 웹 사이트에 대한 많은 네트워크 액세스를 생산할까 봐 걱정된다. 어떻게해야합니까?Nodejs : URL 목록이 포함 된 비동기 요청

urlList.forEach((url, index) => { 

    console.log('Fetching ' + url); 
    request(url, function(error, response, body) { 
     //do sth for body 

    }); 
}); 

나는 하나 개의 요청이 완료된 후 하나 개의 요청이라고합니다 : 여기

내가 뭐하는 거지입니다. 당신이 볼 필요

답변

0

일들은 다음과 같습니다 대상 사이트가 제한 속도를 가지고 있으며, 당신이 너무 많이 너무 빨리 요청하려고하면 당신이 액세스가 차단 될 수 있습니다

  1. 여부?

  2. 성능 저하없이 대상 사이트에서 처리 할 수있는 동시 요청 수는 몇 개입니까?

  3. 서버의 대역폭이 얼마 남았습니까?

  4. 과도한 메모리 사용이나 고정 된 CPU를 유발하지 않고 서버가 얼마나 많은 동시 요청을 처리하고 처리 할 수 ​​있는지를 나타냅니다.

일반적으로이 모든 것을 관리하는 체계는 시작한 요청 수를 조정하는 방법을 만드는 것입니다. 동시 요청 수, 초당 요청 수, 사용 된 데이터의 양 등에 의해이를 제어하는 ​​여러 가지 방법이 있습니다.

시작하는 가장 간단한 방법은 몇 개의 동시 요청을 제어하는 ​​것입니다. (더 이상 거기에 시간 요소를 추가하여

const rp = require('request-promise'); 

// run the whole urlList, no more than 10 at a time 
runRequests(urlList, 10, function(url) { 
    return rp(url).then(function(data) { 
     // process fetched data here for one url 
    }).catch(function(err) { 
     console.log(url, err); 
    }); 
}).then(function() { 
    // all requests done here 
}); 

이 원하는대로 정교한으로 만들 수 있습니다 : 다음과 같은 것을 사용하는 것이,

function runRequests(arrayOfData, maxInFlight, fn) { 
    return new Promise((resolve, reject) => { 
     let index = 0; 
     let inFlight = 0; 

     function next() { 
      while (inFlight < maxInFlight && index < arrayOfData.length) { 
       ++inFlight; 
       fn(arrayOfData[index++]).then(result => { 
        --inFlight; 
        next(); 
       }).catch(err => { 
        --inFlight; 
        console.log(err); 
        // purposely eat the error and let the rest of the processing continue 
        // if you want to stop further processing, you can call reject() here 
        next(); 
       }); 
      } 
      if (inFlight === 0) { 
       // all done 
       resolve(); 
      } 
     } 
     next(); 
    }); 
} 

을 그리고 : 그건은 다음과 같이 수행 할 수 있습니다 초당 N 개의 요청보다 많음) 또는 그것에 대한 대역폭 요소 일 수도 있습니다.

하나의 요청이 완료되면 하나의 요청이 완료되기를 원합니다.

매우 느린 방법입니다. 정말로 원한다면 위의 함수에 maxInFlight 매개 변수에 1을 전달할 수 있지만 대개 5 ~ 50 개의 동시 요청을 허용하여 문제가 발생하지 않으며 훨씬 빠르게 작동합니다. 테스트를 통해서만 특정 대상 사이트와 특정 서버 인프라 및 결과에 대해 수행해야하는 처리량에 적합한 지점을 알 수 있습니다.