概述
在正常狀況下Feign有三種客戶端實現:java
-
Client.Default
類:默認的 feign.Client 客戶端實現類,內部使用HttpURLConnnection
完成HTTP URL請求處理;git -
ApacheHttpClient
類:內部使用Apache httpclient
開源組件完成HTTP URL請求處理的feign.Client 客戶端實現類;github -
OkHttpClient
類:內部使用OkHttp3
開源組件完成HTTP URL請求處理的feign.Client 客戶端實現類。web
@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 { ... }
在前面一節內容中咱們看到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 clientFactory, HttpClient httpClient) { ApacheHttpClient delegate = new ApacheHttpClient(httpClient); return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory); } }
從代碼 @ConditionalOnClass({ApacheHttpClient.class})
註解可知,只須要在pom文件上加上 HttpClient
依賴便可。另外須要在配置文件中配置 feign.httpclient.enabled
爲 true
,從@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 clientFactory, okhttp3.OkHttpClient okHttpClient) { OkHttpClient delegate = new OkHttpClient(okHttpClient); return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory); } }
查看註解咱們知道要使用OkHttp必須知足兩個條件:
-
必須知足
OkHttpClient.class
在當前類路徑中存在,即引入相應依賴 -
必需要配置
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 |
三個客戶端中性能最好的!
測試結果分析
經過上面測試結果(默認配置)咱們很明顯能夠得出如下兩個結論:
-
OKHttp性能優於其餘兩種,推薦使用!
-
在高併發狀況下
Apache httpclient
效率甚至尚未默認的HttpURLConnection
效率高。且在壓測過程當中,發現使用鏈接池請求卡頓現象很容易出現,apache httpclient
甚至還出現請求卡死狀況。httpclient最不推薦使用。
容器優化
Undertow
是一個用java編寫的靈活的高性能Web服務器,提供基於NIO的阻塞和非阻塞API。相比於 tomcat
,Undertow
的性能更高,更輕量。藉此機會咱們恰好看看 Undertow
加 OkHttp
的測試效果。
首先咱們須要引入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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。