Closed johannesherr closed 3 weeks ago
The cause is that
SSLContext ctx = ...;
System.out.println(ctx.getSocketFactory());
System.out.println(ctx.getSocketFactory());
gets 2 factories
sun.security.ssl.SSLSocketFactoryImpl@35cabb2a
sun.security.ssl.SSLSocketFactoryImpl@7e07db1f
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.)