Java HttpURLConnection and pooling

2019-01-20 01:49发布

After reading all sort of docs on Java HttpURLConnection, I'm still quite confused as what kind of pooling it does and how it hands connections.

For example, the following code

URL url = new URL(someUrl);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
OutputStream os = connection.getOutputStream();
InputStream is = connection.getInputStream();

/** Write something to os and flush */
/** Read from is */

os.close();
is.close();
connection.disconnect();
  1. Do both os and is need to be flushed and closed for the underlying socket to be reusable?

  2. Will connection.disconnect() close the underlying socket (and hence make it unreusable)? Does keep-alive affect this behavior?

  3. If I use different URL objects, but with the same URL, will the connections created from them share the underlying sockets? How about when the host part of the URL is the same, but paths are different?

  4. When will pooled connections be destroyed?

  5. What's the system property that controls the size of the pool?

Additionally, if you could also compare the Android version with Java it would be great.

Thanks

标签: java sockets tcp
2条回答
迷人小祖宗
2楼-- · 2019-01-20 02:19

Actually, the accepted answer is not applicable to Android at all:

  1. Both the http.keepAlive and http.maxConnections system properties are ignored by Android because the networking code reads these properties during static initialization (i.e. during process/JVM creation, not checking if they change later). See https://code.google.com/archive/p/android-developer-preview/issues/2578.

  2. This comment is incorrect, as connection pooling is indeed supported in Android (seen next item for more details):

    I believe that Android doesn't do pooling at all, but this should change when they switch to the OpenJDK source.

  3. The connection pooling implemented in OkHttp (which is the implementation under Android's HttpUrlConnection class) treats the count as a global limit across all servers (default is 5). This is actually a bug and doesn't match the standard Java implementation. See https://github.com/square/okhttp/issues/1843.

I encountered this trying to disable connection pooling and found that neither had any effect (confirmed with Android O as well). Instead, Android/OkHttp would consistently reuse 5 connections left over from previous http requests.

查看更多
Rolldiameter
3楼-- · 2019-01-20 02:36
  1. Do both os and is need to be flushed and closed for the underlying socket to be reusable?

Closing the input stream is sufficient. You can't flush an input stream, and flushing an output stream before close is redundant.

  1. Will connection.disconnect() close the underlying socket (and hence make it unreusable)?

It 'acts as a hint' to close the underlying connection.

Does keep-alive affect this behavior?

Yes. If it isn't present, the connection must be closed.

  1. If I use different URL objects, but with the same URL, will the connections created from them share the underlying sockets?

Yes.

How about when the host part of the URL is the same, but paths are different?

Yes.

  1. When will pooled connections be destroyed?

After an idle timeout.

  1. What's the system property that controls the size of the pool?

I'm not aware that there is one, but if there is it will be defined in the Networking Properties page which you can find via the Javadoc.

Additionally, if you could also compare the Android version with Java it would be great.

I believe that Android doesn't do pooling at all, but this should change when they switch to the OpenJDK source.

查看更多
登录 后发表回答