HttpClient (4.1.3 or 4.2-beta)
을 사용하여 62 개의 대상 호스트에서 4500 개 이상의 html 페이지를 다운로드하는 응용 프로그램이 있습니다. 그것은 윈도우 7 64 비트에서 실행됩니다. 프로세서 - Core i7 2600K. 네트워크 대역폭 - 54 Mb/s. 이때HttpClient 멀티 스레드 성능
는 그러한 파라미터를 사용
DefaultHttpClient
PoolingClientConnectionManager
을하고;- 또한
IdleConnectionMonitorThread
부터
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html
까지입니다. - 최대 총 연결 = 80;
- 경로 당 기본 최대 연결 수 = 5; 스레드 관리를 위해
- 그것은 Windows 작업에 (병렬
수준 = 5 (나는 그것이 작동
스레드의 숫자 인 것을 올바르게 이해합니까?)
을이 경우 내 네트워크 사용과 ForkJoinPool
를 사용 관리자) 2.5 % 이상 상승하지 않습니다. 4500 페이지를 다운로드하려면 70 분이 걸립니다.
DEBUG ForkJoinPool-2-노동자 1 [org.apache.http.impl.conn.PoolingClientConnectionManager] : 그리고 HttpClient를 로그에 나는 그런 일이 발표 연결 : [ID : 209] [경로 : {} -> http://stackoverflow.com] [총 보관 된 : 6; 할당 된 경로 : 1 of 5; 총 할당량 : 10 of 80]
총 할당 연결 수가 최대 80 개로 설정되었지만 할당 된 연결 수가 10-12 개를 초과하지 않습니다. 병렬 처리 수준을 20 또는 80으로 올리려고하면 네트워크 사용량은 동일하게 유지되지만 많은 연결 시간 제한이 생성됩니다.
hc.apache.org (HttpClient Performance Optimization Guide 및 HttpClient Threading Guide)에 대한 튜토리얼을 읽었으나 도움이되지 않습니다.
public class ContentDownloader extends RecursiveAction {
private final HttpClient httpClient;
private final HttpContext context;
private List<Entry> entries;
public ContentDownloader(HttpClient httpClient, List<Entry> entries){
this.httpClient = httpClient;
context = new BasicHttpContext();
this.entries = entries;
}
private void computeDirectly(Entry entry){
final HttpGet get = new HttpGet(entry.getLink());
try {
HttpResponse response = httpClient.execute(get, context);
int statusCode = response.getStatusLine().getStatusCode();
if ((statusCode >= 400) && (statusCode <= 600)) {
logger.error("Couldn't get content from " + get.getURI().toString() + "\n" + response.toString());
} else {
HttpEntity entity = response.getEntity();
if (entity != null) {
String htmlContent = EntityUtils.toString(entity).trim();
entry.setHtml(htmlContent);
EntityUtils.consumeQuietly(entity);
}
}
} catch (Exception e) {
} finally {
get.releaseConnection();
}
}
@Override
protected void compute() {
if (entries.size() <= 1){
computeDirectly(entries.get(0));
return;
}
int split = entries.size()/2;
invokeAll(new ContentDownloader(httpClient, entries.subList(0, split)),
new ContentDownloader(httpClient, entries.subList(split, entries.size())));
}
}
을 그리고 질문은 - A는 ConnectionManager
및 HttpClient
을 설정하는 몇 가지 규칙이있을 수 있습니다, 멀티 HttpClient
스레드 사용하는 가장 좋은 방법은 무엇입니까 :
작업의 코드는 다음과 같습니다? 어떻게 80 개의 모든 연결을 사용하고 네트워크 사용을 높일 수 있습니까?
필요한 경우 더 많은 코드를 제공합니다.
콘텐츠 처리를 모두 제거했지만 변경된 사항은 없습니다. 이 문제는 이것과 동일한 문제로 발생할 수 있습니까? [http://stackoverflow.com/questions/10673517/setmaxforroute-does-not-work-in-threadsafeclientconnmanager](http://stackoverflow.com/questions/10673517/setmaxforroute -does-not-work-in-threadsafeclientconnmanager)? – peppered
UPD : 콘텐츠 처리시 CPU로드가 약 0-1 %입니다. – peppered
@pepper : 이것은 의미가 없습니다. 콘텐츠 처리를 제거한 경우 응용 프로그램은 이후의 가져 오기를 위해 어떻게 링크를 추출합니까? – oleg