Android的HttpClient的性能比较性能、Android、HttpClient

2023-09-04 23:59:10 作者:捞起月亮的渔民

我开发Android应用程序,它使用了大量的HTTP请求到Web服务。起初,我创建的每个请求之前,一个新的HttpClient的实例。 为了提高性能,我尝试做多线程的请求。所以,我创建一个HttpClient的实例,所有线程共享,使用ThreadSafeConnectionManager:

I developing android app which uses a lot of http requests to web service. At first, I was creating a new HttpClient instance before every request. To increase performance I try to do requests in many threads. So, I created single HttpClient instance, shared by all threads, using ThreadSafeConnectionManager:

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);

但性能下降,出乎我的意料。我有分寸的时间,将spended到exequte以这样的方式请求:

But performance decreased, to my surprise. I have measured time, to be spended to exequte requests in such way:

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

下面这个是一个日志,其中我与简单的DefaultHttpClient不带参数的每个请求的新实例:

Here this is a log, which I get with simple DefaultHttpClient without parameters new instance per request:

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的实例:

And what I get with ThreadSafeClientConnManager and single HttpClient instance:

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

会发生什么事,我该怎么打呢?

What happens and how can I fight this?

更新

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

Use keep-alive advantage - is what I want. But when I create new HttpClient instance for every request connection can not be reused. Despite of this, such version runs faster, reasons of it is unclear for me.

推荐答案

这一切都很简单。 HttpClient的每默认情况下只允许两个并发连接到同一个目标主机所要求的HTTP规范。这样,有效地你的工作线程花费大部分阻止它们的执行时间等待这两个连接变得可用。

It is all very simple. HttpClient per default allows only two concurrent connections to the same target host as required by the HTTP specification. So, effectively your worker threads spend most of their execution time blocked waiting for those two connections to become available.

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

You should increase the 'max connections per route' limit to reduce / eliminate worker thread contention.

您可能也想看看Apache使用HttpComponents项目来衡量的HttpClient。业绩基准

You might also want to check out the benchmark used by Apache HttpComponents project to measure performance of HttpClient.

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