SpringCloud Alibaba 微服務實戰二十三 - Feign 性能調優

概述

在正常狀況下Feign有三種客戶端實現:java

  1. Client.Default類:默認的 feign.Client 客戶端實現類,內部使用 HttpURLConnnection 完成HTTP URL請求處理;git

  2. ApacheHttpClient 類:內部使用 Apache httpclient開源組件完成HTTP URL請求處理的feign.Client 客戶端實現類;github

  3. OkHttpClient類:內部使用 OkHttp3 開源組件完成HTTP URL請求處理的feign.Client 客戶端實現類。web

@ConditionalOnClass({ ILoadBalancer.classFeign.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 {
 ...
}

在前面一節內容中咱們看到Feign默認客戶端實現 HttpURLConnnection性能不是很好,與Dubbo RPC的性能相差很大。基於 HttpURLConnnection的測試結果以下:spring

聚合報告apache

平均響應時間 吞吐量 最小響應時間 最大響應時間
6866ms 59.5/sec 3056ms 12232ms

本章內容咱們須要對Feign的全部客戶端進行性能測試,以此來肯定選擇一個最優的客戶端調用工具。tomcat

測試工具

測試服務器:Intel Core i5-7200U CPU @ 2.50GHz 2.70GHz  6核 16G內存服務器

測試工具:JMeter5.1微信

線程數:1000架構

Ramp-Up : 10

JMeter測試工具

「ps : 本文中出現的全部性能測試結果我都至少測試過10遍以上,最後選取的是一個相對平均的結果,測試結果相對仍是比較準確的。」

HttpClient

首先咱們先將客戶端工具切換到HttpClient,查看HttpClientFeignLoadBalancedConfiguration配置類,源碼以下

@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 clientFactoryHttpClient httpClient{
  ApacheHttpClient delegate = new ApacheHttpClient(httpClient);
  return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
 }

}

從代碼 @ConditionalOnClass({ApacheHttpClient.class})註解可知,只須要在pom文件上加上 HttpClient依賴便可。另外須要在配置文件中配置 feign.httpclient.enabledtrue從@ConditionalOnProperty註解可知,這個配置能夠不寫,由於在默認狀況下就爲true。

因此要使用HttpClient咱們只須要在消費者模塊 order-service引入httpclient依賴便可:

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

測試結果

聚合報告

平均響應時間 吞吐量 最小響應時間 最大響應時間
8390ms 48.5/sec 2691ms 20371ms

在高併發下性能測試竟然比不過原生的 HttpURLConnnection ,有點點失望!

OkHttp

一樣先查看okhttp的配置類 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 clientFactoryokhttp3.OkHttpClient okHttpClient{
  OkHttpClient delegate = new OkHttpClient(okHttpClient);
  return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
 }

}

查看註解咱們知道要使用OkHttp必須知足兩個條件:

  1. 必須知足 OkHttpClient.class 在當前類路徑中存在,即引入相應依賴

  2. 必需要配置 feign.okhttp.enabled配置項的值爲true

因此這裏我先引入OkHttp的依賴:

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

而後修改配置文件,開啓OkHttp:

feign:
...
  okhttp:
    enabled: true

測試結果

聚合報告

平均響應時間 吞吐量 最小響應時間 最大響應時間
5335ms 66.3/sec 1874ms 9011ms

三個客戶端中性能最好的!

測試結果分析

經過上面測試結果(默認配置)咱們很明顯能夠得出如下兩個結論:

  1. OKHttp性能優於其餘兩種,推薦使用!

  2. 在高併發狀況下 Apache httpclient效率甚至尚未默認的 HttpURLConnection效率高。且在壓測過程當中,發現使用鏈接池請求卡頓現象很容易出現, apache httpclient 甚至還出現請求卡死狀況。httpclient最不推薦使用。

容器優化

Undertow是一個用java編寫的靈活的高性能Web服務器,提供基於NIO的阻塞和非阻塞API。相比於 tomcatUndertow的性能更高,更輕量。藉此機會咱們恰好看看 UndertowOkHttp的測試效果。

首先咱們須要引入undertow的依賴並排除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>

測試效果

聚合報告

平均響應時間 吞吐量 最小響應時間 最大響應時間
3817ms 71.7/sec 1830ms 6174ms

經過測試效果能夠看出,使用了undertow容器後,性能又有了小小的提高。

總結

本文中的全部測試結論都是基於組件的默認配置,對於那些追求性能而又不想對參數進行調優的能夠考慮 OkHttp + Undertow的組合,雖然沒辦法與dubbo等rpc協議性能相比,可是在springcloud架構中的http調用,這二者之間的組合性能最高。

最後爲了方便你們直觀比較,將Feign原生 HttpURLConnnection的測試結果和基於 OkHttp + Undertow的測試結果放一塊兒供你們參考:

  • HttpURLConnnection

平均響應時間 吞吐量 最小響應時間 最大響應時間
6866ms 59.5/sec 3056ms 12232ms
  • OkHttp + Undertow

平均響應時間 吞吐量 最小響應時間 最大響應時間
3817ms 71.7/sec 1830ms 6174ms

 

若是本文對你有幫助,別忘記來個三連:點贊,轉發,評論。我們下期見!

 

本文分享自微信公衆號 - JAVA日知錄(javadaily)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索