gpt4 book ai didi

java - HttpClient 多线程性能

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:53:40 25 4
gpt4 key购买 nike

我有一个应用程序使用 HttpClient(4.1.3 或 4.2-beta) 从 62 个目标主机下载超过 4500 个 html 页面。它在 Windows 7 64 位上运行。处理器——酷睿 i7 2600K。网络带宽 - 54 Mb/s。

此时它使用这样的参数:

  • DefaultHttpClientPoolingClientConnectionManager
  • 它还有来自
    IdleConnectionMonitorThreadhttp://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html;
  • 最大总连接数 = 80;
  • 每条路线的默认最大连接数 = 5;
  • 对于线程管理,它使用具有并行性的ForkJoinPool
    level = 5 (我是否理解正确,它是一些工作
    线程?)

在这种情况下,我的网络使用率(在 Windows 任务管理器中)不会超过 2.5%。下载 4500 页需要 70 分钟。在 HttpClient 日志中我有这样的东西:

DEBUG ForkJoinPool-2-worker-1 [org.apache.http.impl.conn.PoolingClientConnectionManager]: Connection released: [id: 209][route: {}->http://stackoverflow.com][total kept alive: 6; route allocated: 1 of 5; total allocated: 10 of 80]

分配的连接总数不会超过 10-12,尽管我已将其设置为 80 个连接。如果我尝试将并行度级别提高到 20 或 80,网络使用率保持不变,但会产生很多连接超时。

我已经阅读了 hc.apache.org 上的教程(HttpClient Performance Optimization GuideHttpClient 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())));
}
}

问题是 - 使用多线程 HttpClient 的最佳实践是什么,可能有一些设置 ConnectionManagerHttpClient< 的规则?如何使用所有 80 个连接并提高网络使用率?

如有必要,我会提供更多代码。

最佳答案

我不确定您从多少个不同的主机中拉出,但如果它是一个小数字(或只有 1 个),您想要增加每个路由的最大值。这将增加每个主机的并发性。

目前您已将其设置为 5。您观察到的最大连接使用量高达 10-12,也许您只访问了 2-3 个不同的主机,在这种情况下,数学相加。

关于java - HttpClient 多线程性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10682612/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com