2012-11-01 3 views
1

처리해야하는 수백만 줄의 파일이 있습니다. 파일의 각 행은 HTTP 호출이됩니다. 나는 그 문제를 공격하는 가장 좋은 방법을 찾아 내려고 노력하고있다.Java에서 HTTP 호출 용 대형 파일 처리

분명히 파일을 읽고 순차적으로 전화를 걸 수는 있지만 엄청 느려질 것입니다. 나는 호출을 병렬 처리하고 싶지만 전체 파일을 메모리로 읽어야하는지 (파일의 큰 팬이 아님) 또는 파일의 읽기를 병렬화하려고하는지 잘 모르겠다. 모르겠다.)

문제를 공격하는 가장 좋은 방법에 대해 생각해보십시오. 비슷한 것을하는 기존의 프레임 워크 나 라이브러리가 있다면 그것을 사용해도 행복합니다.

감사합니다.

+0

큰 파일에는 몇 개의 URL이 있습니까? – Steve

+0

'수백만 줄'이란 말은 수백만 개의 URL을 의미합니다 ... – talnicolas

+0

수백만 개의 데이터가 URL + HTTP 본문의 나머지 부분에 어셈블됩니다. – Nick

답변

5

내가 전화를 병렬화하고 싶습니다,하지만 당신은 경계 BlockingQueue와 함께 ExecutorService을 사용한다 메모리

에 전체 파일을 읽어야하는 경우 잘 모르겠어요. 백만 라인을 읽으면 BlockingQueue이 가득 찰 때까지 스레드 풀에 작업을 제출합니다. 이 방법을 사용하면 미리 파일의 모든 행을 읽지 않아도 HTTP 요청을 동시에 100 개 (또는 원하는 수만큼) 실행할 수 있습니다.

대기열이 가득 차면 차단하는 RejectedExecutionHandler을 설정해야합니다. 이것은 호출자 실행 핸들러보다 낫습니다.

BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(100); 
// NOTE: you want the min and max thread numbers here to be the same value 
ThreadPoolExecutor threadPool = 
    new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, queue); 
// we need our RejectedExecutionHandler to block if the queue is full 
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() { 
     @Override 
     public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { 
      try { 
       // this will block the producer until there's room in the queue 
       executor.getQueue().put(r); 
      } catch (InterruptedException e) { 
       throw new RejectedExecutionException(
        "Unexpected InterruptedException", e); 
      } 
    } 
}); 

// now read in the urls 
while ((String url = urlReader.readLine()) != null) { 
    // submit them to the thread-pool. this may block. 
    threadPool.submit(new DownloadUrlRunnable(url)); 
} 
// after we submit we have to shutdown the pool 
threadPool.shutdown(); 
// wait for them to complete 
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); 

... 
private class DownloadUrlRunnable implements Runnable { 
    private final String url; 
    public DownloadUrlRunnable(String url) { 
     this.url = url; 
    } 
    public void run() { 
     // download the URL 
    } 
} 
+0

굉장합니다. 내가 뭘 찾고 있었는지. 파트 타임 코더로서, 멀티 스레딩은 항상 저에게 엉덩이의 고통이었습니다. 도와 주셔서 감사합니다! – Nick

0

그레이의 접근 방식이 좋은 것처럼 보입니다. 내가 제안 할 다른 접근법은 청크로 파일을 분할하는 것입니다 (논리를 작성해야 함). 다중 스레드로 처리해야합니다.