Overview
Under normal circumstances, Feign has three client implementations:
-
Client.Default
Class: The default feign.Client client implementation class, used internally toHttpURLConnnection
complete HTTP URL request processing; -
ApacheHttpClient
Class:Apache httpclient
feign.Client client implementation class that uses open source components to complete HTTP URL request processing; -
OkHttpClient
Class: Internal useOkHttp3
Open source component completes the feign.Client client implementation class of HTTP URL request processing.
@ConditionalOnClass({ ILoadBalancer.class, Feign.class })
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.ribbon.enabled",
matchIfMissing = true)
@Configuration(proxyBeanMethods = false)
@AutoConfigureBefore(FeignAutoConfiguration.class)
@EnableConfigurationProperties({ FeignHttpClientProperties.class })
@Import({ HttpClientFeignLoadBalancedConfiguration.class,
OkHttpFeignLoadBalancedConfiguration.class,
DefaultFeignLoadBalancedConfiguration.class })
public class FeignRibbonClientAutoConfiguration {
...
}
In the previous section we saw Feign default client implementation HttpURLConnnection
performance is not very good, and the performance of Dubbo RPC's a big difference. Based on HttpURLConnnection
the test results are as follows:
Average response time | Throughput | Minimum response time | Maximum response time |
---|---|---|---|
6866ms | 59.5/sec | 3056ms | 12232ms |
In this chapter, we need to perform performance tests on all Feign clients to determine the best client invocation tool.
test tools
Test server: Intel Core i5-7200U CPU @ 2.50GHz 2.70GHz 6 core 16G memory
Test tool: JMeter5.1
Number of threads: 1000
Ramp-Up : 10
"Ps: I have tested all the performance test results in this article at least 10 times, and finally selected a relatively average result. The test results are relatively accurate."
HttpClient
First, we first switch the client tool to HttpClient, check the HttpClientFeignLoadBalancedConfiguration configuration class, the source code is as follows
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ApacheHttpClient.class)
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
@Import(HttpClientFeignConfiguration.class)
class HttpClientFeignLoadBalancedConfiguration {
@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory, HttpClient httpClient) {
ApacheHttpClient delegate = new ApacheHttpClient(httpClient);
return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
}
}
From the code @ConditionalOnClass({ApacheHttpClient.class})
found comment, just add in the pom file HttpClient
reliance can be. Also needs to be configured in the configuration file feign.httpclient.enabled
as true
, 从@ConditionalOnProperty
notes can be seen, this configuration can not write, because by default it is true.
So we only need to use HttpClient in consumer module order-service
introduced httpclient can rely on:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
Test Results
Average response time | Throughput | Minimum response time | Maximum response time |
---|---|---|---|
8390ms | 48.5/sec | 2691ms | 20371ms |
The performance test under high concurrency is actually not better than the native one HttpURLConnnection
, which is a bit disappointing!
OkHttp
Also check the configuration class of okhttp first OkHttpFeignLoadBalancedConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnProperty("feign.okhttp.enabled")
@Import(OkHttpFeignConfiguration.class)
class OkHttpFeignLoadBalancedConfiguration {
@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory, okhttp3.OkHttpClient okHttpClient) {
OkHttpClient delegate = new OkHttpClient(okHttpClient);
return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
}
}
Looking at the comments, we know that to use OkHttp, two conditions must be met:
-
Must be satisfied
OkHttpClient.class
Exist in the current classpath, that is, introduce the corresponding dependency -
feign.okhttp.enabled
The value of the configuration item must be configured to be true
So here I first introduce the dependency of OkHttp:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
Then modify the configuration file and enable OkHttp:
feign:
...
okhttp:
enabled: true
Test Results
Average response time | Throughput | Minimum response time | Maximum response time |
---|---|---|---|
5335ms | 66.3/sec | 1874ms | 9011ms |
The best performance of the three clients!
Test result analysis
Through the above test results (default configuration) we can clearly draw the following two conclusions:
-
OKHttp has better performance than the other two, it is recommended!
-
In the case of high concurrency, the
Apache httpclient
efficiency is not even asHttpURLConnection
high as the default . And in the process of stress testing, it was found that the use of connection pool request stuck phenomenon is very easy to occur,apache httpclient
and even the request stuck situation. httpclient is least recommended.
Container optimization
Undertow
It is a flexible high-performance web server written in java, providing blocking and non-blocking API based on NIO. Compared with tomcat
, Undertow
the performance is higher and lighter. We just like to take this opportunity to look at Undertow
adding OkHttp
the test results.
First, we need to introduce the dependency of undertow and exclude the dependency of tomcat:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
Test effect
Average response time | Throughput | Minimum response time | Maximum response time |
---|---|---|---|
3817ms | 71.7/sec | 1830ms | 6174ms |
Through the test results, it can be seen that after using the undertow container, the performance has been slightly improved.
to sum up
All test results in this paper are based on the default configuration of components, for those who seek performance but do not want to consider the parameters tuning OkHttp + Undertow
combinations, although no way compared to the protocol performance dubbo and other rpc, but in springcloud architecture http call, the combination between the two has the highest performance.
Finally, in order to facilitate visual comparison, the Feign native HttpURLConnnection
of test results and based on OkHttp + Undertow
the test results put together for your reference:
-
HttpURLConnnection
Average response time | Throughput | Minimum response time | Maximum response time |
---|---|---|---|
6866ms | 59.5/sec | 3056ms | 12232ms |
-
OkHttp + Undertow
Average response time | Throughput | Minimum response time | Maximum response time |
---|---|---|---|
3817ms | 71.7/sec | 1830ms | 6174ms |
If this article is helpful to you,
Don't forget to come to a three-link:
Like, repost, comment.
See you next time! Favorite equal to the white prostitute , thumbs up is the truth!
SpringCloud alibaba series actual combat