Skip to content

ReactorClientHttpConnector creates new HttpClient for every request #33093

@kzander91

Description

@kzander91

In 6.1.9, since commit 7785f94 (related issue: #32945), this.httpClient is no longer assigned. The assignment should probably have happened here:

if (httpClient == null) {
Assert.state(this.resourceFactory != null && this.mapper != null, "Illegal configuration");
httpClient = createHttpClient(this.resourceFactory, this.mapper);
}

As a consequence, a new HttpClient instance is created for every request. Apart from the possible performance impact, this is causing a memory leak in my application: I'm using client certificate authentication configured through Boot's SslBundle support. This causes the creation of new SslContext instances alongside each new HttpClient in org.springframework.boot.autoconfigure.web.reactive.function.client.ReactorClientHttpConnectorFactory.
Then, because Netty's SslContext implementations don't implement hashCode(), Reactor Netty's connection pooling doesn't work properly, causing new HTTP connection pools to be created for every request (config.channelHash() returns distinct values for every request https://github.com/reactor/reactor-netty/blob/v1.1.20/reactor-netty-core/src/main/java/reactor/netty/resources/PooledConnectionProvider.java#L127-L133).
All these connection pools are then never disposed of (this is Reactor Netty's default configuration I believe), eventually causing an OOME.


TL;DR

  • Reactor Netty creates a new HTTP connection pool for every HTTP request, because
  • it includes the hash code of Netty's SslContext in the pool key, because
  • an SslContext has been configured by Spring Boot's SslBundle feature for every request, because
  • Spring Framework creates new HttpClient instances for every request.

The leak itself may be fixed in Netty (should SslContext implementations have stable hash codes?), but it was surfaced by the commit in Spring Framework.

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)type: regressionA bug that is also a regression

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions