You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using the same client instance and making requests to the same URL the TCP connection should be reused via the Java KeepAliveCache. This worked until version 2.40 and does no longer work in version 2.41-2.43. Now for every request a new TCP connection is created (but still put into the cache), which leads to a large number of established connections.
To reproduce you can run this snippet:
public static void main(String[] args) throws Exception {
Client client = ClientBuilder.newClient();
for (int i = 0; i < 2; i++) {
try (Response response = client.target("https://www.spiegel.de")
.request()
.get()) {
response.readEntity(String.class);
System.out.println(String.format("response = %s", response));
Thread.sleep(1000);
}
}
Thread.sleep(Long.MAX_VALUE);
}
With version 2.40 only one connection will be created, from 2.41 on it will be two.
The cause seems to be that when looking for a previous connection in the KeepAliveCache:
/**
* Check to see if this URL has a cached HttpClient
*/
public HttpClient get(URL url, Object obj) {
cacheLock.lock();
try {
KeepAliveKey key = new KeepAliveKey(url, obj);
ClientVector v = super.get(key);
if (v == null) { // nothing in cache yet
return null;
}
return v.get();
} finally {
cacheLock.unlock();
}
}
The second parameter obj is a sun.security.ssl.SSLSocketFactoryImpl instance. It is part of the cache key. So only if the same instance is used for a lookup a previous connection will be found. This is the case for older versions (I added an Intellij breakpoint to print the arguments):
get https://www.spiegel.de sun.security.ssl.SSLSocketFactoryImpl@5bfa8cc5
get https://www.spiegel.de sun.security.ssl.SSLSocketFactoryImpl@5bfa8cc5
But not for new versions:
get https://www.spiegel.de sun.security.ssl.SSLSocketFactoryImpl@13e3c1c7
get https://www.spiegel.de sun.security.ssl.SSLSocketFactoryImpl@20312893
Since different SSLSocketFactoryImpl instances are used, the cache lookup always fail and always a new connection is created. So we see the number of established connections explode in production after the update.
I assume some change lead to new instances of SSLSocketFactoryImpl being created for new requests, even though the client is reused.
(The Java version is irrelevant. I tested with 17 and 21.)
The text was updated successfully, but these errors were encountered:
When using the same client instance and making requests to the same URL the TCP connection should be reused via the Java
KeepAliveCache
. This worked until version 2.40 and does no longer work in version 2.41-2.43. Now for every request a new TCP connection is created (but still put into the cache), which leads to a large number of established connections.To reproduce you can run this snippet:
With version 2.40 only one connection will be created, from 2.41 on it will be two.
The cause seems to be that when looking for a previous connection in the KeepAliveCache:
The second parameter
obj
is asun.security.ssl.SSLSocketFactoryImpl
instance. It is part of the cache key. So only if the same instance is used for a lookup a previous connection will be found. This is the case for older versions (I added an Intellij breakpoint to print the arguments):But not for new versions:
Since different
SSLSocketFactoryImpl
instances are used, the cache lookup always fail and always a new connection is created. So we see the number of established connections explode in production after the update.I assume some change lead to new instances of
SSLSocketFactoryImpl
being created for new requests, even though the client is reused.(The Java version is irrelevant. I tested with 17 and 21.)
The text was updated successfully, but these errors were encountered: