Open BenEfrati opened 2 years ago
https://github.com/spring-projects/spring-boot/issues/31075#issuecomment-1128766582
the piece code instantiating the request factory should be in charge of closing resources properly
Hello, @BenEfrati , thanks for reporting it. Looks like a bug.
Recently, I encountered this problem in the production environment. I found that the HttpClient
was created many times. The HttpClient
connection pool did not enable the thread for clearing expired connections. The problem was solved by sharing one HttpClient
and enabling the IdleConnectionEvaluator
thread. The code is as follows:
@Configuration
public class EurekaConfig {
private final AtomicReference<CloseableHttpClient> ref = new AtomicReference<>();
@Bean
public EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier() {
return (sslContext, hostnameVerifier) -> {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
HttpClientBuilder httpClientBuilder = HttpClients
.custom()
.evictExpiredConnections()
.evictIdleConnections(30L, TimeUnit.SECONDS);
if (sslContext != null) {
httpClientBuilder = httpClientBuilder.setSSLContext(sslContext);
}
if (hostnameVerifier != null) {
httpClientBuilder = httpClientBuilder.setSSLHostnameVerifier(hostnameVerifier);
}
if (ref.get() == null) {
ref.compareAndSet(null, httpClientBuilder.build());
}
requestFactory.setHttpClient(ref.get());
return requestFactory;
};
}
}
`
Hello @sdzx3783 - thanks for your comment. Would you like to submit a PR with a fix?
I provide a temporary solution without changing the source code
Hi @OlgaMaciaszek , may I know which version will include the fix?
@dangkhoaphung if the issue is added to an active backlog, it will be assigned a milestone. We're now prioritising tasks for the upcoming release and will circle back to non-blocking issues later on. However, feel free to create a PR, and we will definitely review it.
Initial fix reverted due to https://github.com/spring-cloud/spring-cloud-netflix/issues/4275. Reopening.
Spring Cloud 2021.0.0 Spring Boot 2.6.8
Bug Description:
RestTemplateEurekaHttpClient
is not closingHttpClient
on shutdown. This leads to TCPCLOSE_WAIT
connections to eureka server.EurekaClient
will shutdown when an exception occurs on an http request, but not shutdownHttpClient
.This bug is related to https://github.com/spring-cloud/spring-cloud-netflix/blob/27ac3379f6b391ccd605d212512f15c439825ecb/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateEurekaHttpClient.java#L203
In case of exception here: https://github.com/Netflix/eureka/blob/ed0da19ca1c049c87e3dbf75b6015c1861d5c2d0/eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/RedirectingEurekaHttpClient.java#L96 new
HttpClient
will be created without closing the existing one - this causesCLOSE_WAIT
connectionsThis supplier creates new
CloseableHttpClient
for every call to https://github.com/spring-cloud/spring-cloud-netflix/blob/27ac3379f6b391ccd605d212512f15c439825ecb/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateTransportClientFactory.java#L103so in case of shutdown,
currentEurekaClient
shutdown don't closes connections: https://github.com/spring-cloud/spring-cloud-netflix/blob/27ac3379f6b391ccd605d212512f15c439825ecb/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateEurekaHttpClient.java#L203possible solution will be trying to close the
HttpClient
:shutdown
could beunwrapRequestFactoryIfNecessary
https://github.com/spring-projects/spring-boot/blob/47516b50c39bd6ea924a1f6720ce6d4a71088651/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilder.java#L746spring-projects/spring-boot#31075
As you can see process open files increases over time until GC occurred
We can also create
EurekaClientHttpRequestFactorySupplier
which return the sameClientHttpRequestFactory
, but it not a stable solution since we can't control eureka client code, maybe in case of exceptions connections not closes (hence not returns toPoolingHttpClientConnectionManager
) - this can lead to no available connections in pool. In that case, restart is requiredOriginal Issue: https://github.com/spring-cloud/spring-cloud-netflix/issues/4062