In my mutlithreaded application, I send some http requests, to some http servers, I would say 10 servers, 300 different requests per server, about once an hour, nothing too serious.
My question is: should I keep a single HttpClient for all outgoing connections ? Maybe one per unique target server ? or one per "iteration" (it takes about 10 minutes in the beginning of every hour) ?
I'm currently using a single PoolingHttpClientConnectionManager
, and HttpClientBuilder.setConnectionManager(connectionManager).build()
for every request.
I have a feeling of a real waste of resources, and I also see many connections in ESTABLISHED
state per server, though I'm using a pooling connection manager. (The requests for each server are sent one-by-one, and are not concurrent)
I'm currently using a single PoolingHttpClientConnectionManager, and HttpClientBuilder.setConnectionManager(connectionManager).build() for every request.
Building a new HttpClient for each request is a huge waste. You should use an HttpClient per configuration (each client can have different connection manager, max concurrent requests, etc) or for each independent module of your application (in order to not create dependencies between otherwise independent modules).
Also do not forget that .build()
returns a CloseableHttpClient
which means that you should call httpClient.close()
when you are done using it otherwise you may leak resources.
Update in responde to a comment from @Nati:
what will be "wasted" ? is HttpClient a heavy object ?
Here you can see the source code for the creation of an http client. As you can see it's a lot of code and is pointless to be executed on each request. This unnecessary consumes CPU and creates a lot of garbage which reduces the performance of the whole application. The less allocations you do - the better! In other words there are no benefits from creating new client for each request - only downsides.
does it make any sense of keeping it as a bean for the entire lifespan of the application
IMHO it does, unless it's used very (very) rarely.
relation between the HttpConnection and HttpClient
Each http client can execute multiple http requests. Each request is executed in the context of the client (it's configuration - i.e proxy, concurrency, keep-alive, etc) Each response to a request has to be closed (reset(), close(), don't remember the exact name) in order to free the connection so it can be reused for another request.