SpringCloud Alibaba微服务实战二十三 - Feign 性能调优
source link: https://segmentfault.com/a/1190000038840773
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
SpringCloud Alibaba微服务实战二十三 - Feign 性能调优
在正常情况下Feign有三种客户端实现:
Client.Default
类:默认的 feign.Client 客户端实现类,内部使用HttpURLConnnection
完成HTTP URL请求处理;ApacheHttpClient
类:内部使用Apache httpclient
开源组件完成HTTP URL请求处理的feign.Client 客户端实现类;OkHttpClient
类:内部使用OkHttp3
开源组件完成HTTP URL请求处理的feign.Client 客户端实现类。
`@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
的测试结果如下:
本章内容我们需要对Feign的所有客户端进行性能测试,以此来确定选择一个最优的客户端调用工具。
测试服务器: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>`
在高并发下性能测试居然比不过原生的 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`
三个客户端中性能最好的!
测试结果分析
通过上面测试结果(默认配置)我们很明显可以得出以下两个结论:
- 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>`
通过测试效果可以看出,使用了undertow容器后,性能又有了小小的提升。
本文中的所有测试结论都是基于组件的默认配置,对于那些追求性能而又不想对参数进行调优的可以考虑 OkHttp + Undertow
的组合,虽然没办法与dubbo等rpc协议性能相比,但是在springcloud架构中的http调用,这两者之间的组合性能最高。
最后为了方便大家直观比较,将Feign原生 HttpURLConnnection
的测试结果和基于 OkHttp + Undertow
的测试结果放一起供大家参考:
- HttpURLConnnection
- OkHttp + Undertow
这里为大家准备了一份小小的礼物,关注公众号,输入如下代码,即可获得百度网盘地址,无套路领取!
001:《程序员必读书籍》
002:《从无到有搭建中小型互联网公司后台服务架构与运维架构》
003:《互联网企业高并发解决方案》
004:《互联网架构教学视频》
006:《SpringBoot实现点餐系统》
007:《SpringSecurity实战视频》
008:《Hadoop实战教学视频》
009:《腾讯2019Techo开发者大会PPT》
010: 微信交流群
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK