Android HttpClient 性能

Android HttpClient performance

我正在开发 Android 应用程序,该应用程序使用了大量对 Web 服务的 http 请求。起初,我在每次请求之前创建一个新的 HttpClient 实例。
为了提高性能,我尝试在多个线程中执行请求。所以,我创建了单个 HttpClient 实例,由所有线程共享,使用 ThreadSafeConnectionManager:

1
2
3
4
5
6
7
8
9
10
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

BasicHttpParams params = new BasicHttpParams();
ConnManagerParams.setMaxTotalConnections(params, 100);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setUseExpectContinue(params, true);

ThreadSafeClientConnManager connManager = new ThreadSafeClientConnManager(params, registry);
HttpClient client = new DefaultHttpClient(connManager, params);

但令我惊讶的是,性能下降了。我已经测量了时间,用于以这种方式执行请求:

1
2
3
4
long startTime = System.currentTimeMillis();
HttpResponse response = client.execute(postRequest);
long reqTime = System.currentTimeMillis() - startTime;
Log.i("SyncTimer","Request time:" + reqTime);

这是一个日志,我使用简单的 DefaultHttpClient 获取,每个请求没有参数新实例:

1
2
3
4
5
6
01-11 11:10:51.136: INFO/SyncTimer(18400): Request time:1076
01-11 11:10:54.686: INFO/SyncTimer(18400): Request time:1051
01-11 11:10:57.996: INFO/SyncTimer(18400): Request time:1054
01-11 11:10:59.166: INFO/SyncTimer(18400): Request time:1070
01-11 11:11:00.346: INFO/SyncTimer(18400): Request time:1172
01-11 11:11:02.656: INFO/SyncTimer(18400): Request time:1043

我用 ThreadSafeClientConnManager 和单个 HttpClient 实例得到了什么:

1
2
3
4
5
6
7
01-11 11:06:06.926: INFO/SyncTimer(18267): Request time:7001
01-11 11:06:10.412: INFO/SyncTimer(18267): Request time:3385
01-11 11:06:20.222: INFO/SyncTimer(18267): Request time:9801
01-11 11:06:23.622: INFO/SyncTimer(18267): Request time:2058
01-11 11:06:29.906: INFO/SyncTimer(18267): Request time:6268
01-11 11:06:34.746: INFO/SyncTimer(18267): Request time:3525
01-11 11:06:50.302: INFO/SyncTimer(18267): Request time:15551

会发生什么,我该如何应对?

更新

使用保活优势 - 这就是我想要的。但是当我为每个请求创建新的 HttpClient 实例时,连接不能被重用。尽管如此,这样的版本运行速度更快,我不清楚原因。


一切都很简单。根据 HTTP 规范的要求,默认情况下 HttpClient 仅允许到同一目标主机的两个并发连接。因此,您的工作线程实际上将大部分执行时间都花在了等待这两个连接可用的状态上。

您应该增加"每条路由的最大连接数"限制以减少/消除工作线程争用。

您可能还想查看 Apache HttpComponents 项目用来衡量 HttpClient 性能的基准。

http://wiki.apache.org/HttpComponents/HttpClient3vsHttpClient4vsHttpCore


我怀疑上下文切换导致线程安全管理器性能不佳,您应该停止使用它。我想您可以将 Apache 客户端与默认的 Java 客户端进行比较,但我认为您不会获得太多的性能提升。

就我个人而言,我发现 DOM XML 解析器有点慢,所以如果您正在使用 XML 重新格式化它可能会有所帮助。根据您的应用程序,您可以在需要之前请求项目或使用缓存来创建更好的用户体验,但我们需要了解更多信息才能为您提供有意义的建议。