SpringCloud Alibaba Microservice Actual Combat 23-Feign Performance Tuning

Overview

Under normal circumstances, Feign has three client implementations:

  1. Client.DefaultClass: The default feign.Client client implementation class, used internally to HttpURLConnnectioncomplete HTTP URL request processing;

  2. ApacheHttpClientClass: Apache httpclientfeign.Client client implementation class that uses open source components to complete HTTP URL request processing;

  3. OkHttpClientClass: Internal use OkHttp3Open 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 HttpURLConnnectionperformance is not very good, and the performance of Dubbo RPC's a big difference. Based on HttpURLConnnectionthe test results are as follows:

Aggregate report

 

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

JMeter test tool

"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 HttpClientreliance can be. Also needs to be configured in the configuration file feign.httpclient.enabledas true, 从@ConditionalOnPropertynotes 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-serviceintroduced httpclient can rely on:

<dependency>
 <groupId>io.github.openfeign</groupId>
 <artifactId>feign-httpclient</artifactId>
</dependency>

Test Results

Aggregate report

 

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:

  1. Must be satisfied OkHttpClient.classExist in the current classpath, that is, introduce the corresponding dependency

  2. feign.okhttp.enabledThe 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

Aggregate report

 

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:

  1. OKHttp has better performance than the other two, it is recommended!

  2. In the case of high concurrency, the Apache httpclientefficiency is not even as HttpURLConnectionhigh 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 httpclientand even the request stuck situation. httpclient is least recommended.

Container optimization

UndertowIt is a flexible high-performance web server written in java, providing blocking and non-blocking API based on NIO. Compared with tomcat, Undertowthe performance is higher and lighter. We just like to take this opportunity to look at Undertowadding OkHttpthe 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

Aggregate report

 

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 + Undertowcombinations, 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 HttpURLConnnectionof test results and based on OkHttp + Undertowthe 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

 

Guess you like

Origin blog.csdn.net/jianzhang11/article/details/111244020