When using Feign, it defaults to using HttpURLConnection. I anticipated performance improvements by switching to Apache HttpClient for connection pooling. However, in my tests, the response time actually increased. I'm curious to know what might be causing this.
The reasons why I believed that using connection pooling reduces the time for API calls are as follows:
Connection Reuse:
Connection Overhead Reduction:
Concurrency Management:
Keep-Alive Utilization:
Resource Efficiency:
HTTP connection pooling is particularly beneficial for web applications handling multiple simultaneous HTTP requests, contributing to enhanced performance.
I conducted tests for two scenarios: one using HttpURLConnection and the other with Apache HttpClient.
I added the Apache HttpClient library to my Spring Boot project and confirmed that the execute() method of Apache HttpClient is being called. Also, I confirmed PoolingHttpClientConnectionManager.class is being used.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
implementation 'io.github.openfeign:feign-httpclient' // 🔥🔥🔥
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
I measured the execution time for the two scenarios mentioned above using the following code:
@SpringBootTest
public class HttpClientTest {
@Autowired
TestFeignClient testFeignClient;
@Test
void testWithMultiThread() {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10000; i++) {
executorService.execute(() -> {
testFeignClient.verifyMember(1);
});
}
executorService.shutdown();
while (!executorService.isTerminated()) {
}
}
}
10000 times(thread 100): 0:00:12.198
10000 times(thread 100): 0:00:15.330
I expected the time to be shorter with Apache HttpClient due to connection pooling, but in 20 test runs, Apache HttpClient took more time in the majority of cases.
The linked you provided use this depedency:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
Now it is crucial to know the configuration and the default settings.
Connection management in Apache HttpClient refers to the management of underlying connections to remote servers. Efficient connection management is crucial for optimizing performance and resource utilization. Apache HttpClient provides various options for configuring connection management.
In this library PoolingHttpClientConnectionManager
manages a pool of client connections and is able to service connection requests from multiple execution threads. It pools connections as per route basis. It maintains a maximum limit of connections on a for each route basis and in total. By default, it creates up to 2 concurrent connections per given route and up to 20 connections in total. For real-world applications, we can increase these limits if needed.
Based on that information you can adjust and increase 2
concurrent connection to more - to test is accurately.
Also check the setting for connections in total.
In the link you provided: https://github.com/OpenFeign/feign/blob/master/httpclient/src/main/java/feign/httpclient/ApacheHttpClient.java
I do not see default change of these options. You need to try to change it yourself based on your needs.