13

SpringCloud Alibaba微服务实战二十三 - Feign 性能调优

 3 years ago
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.
neoserver,ios ssh client

SpringCloud Alibaba微服务实战二十三 - Feign 性能调优

在正常情况下Feign有三种客户端实现:

  1. Client.Default类:默认的 feign.Client 客户端实现类,内部使用HttpURLConnnection 完成HTTP URL请求处理;
  2. ApacheHttpClient 类:内部使用Apache httpclient开源组件完成HTTP URL请求处理的feign.Client 客户端实现类;
  3. 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的测试结果如下:

image.png

本章内容我们需要对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.enabledtrue从@ConditionalOnProperty注解可知,这个配置可以不写,因为在默认情况下就为true。

所以要使用HttpClient我们只需要在消费者模块 order-service引入httpclient依赖即可:

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

image.png

在高并发下性能测试居然比不过原生的 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必须满足两个条件:

  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`

image.png

三个客户端中性能最好的!

测试结果分析

通过上面测试结果(默认配置)我们很明显可以得出以下两个结论:

  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>`

聚合报告

image.png

通过测试效果可以看出,使用了undertow容器后,性能又有了小小的提升。

本文中的所有测试结论都是基于组件的默认配置,对于那些追求性能而又不想对参数进行调优的可以考虑 OkHttp + Undertow的组合,虽然没办法与dubbo等rpc协议性能相比,但是在springcloud架构中的http调用,这两者之间的组合性能最高。

最后为了方便大家直观比较,将Feign原生 HttpURLConnnection的测试结果和基于 OkHttp + Undertow的测试结果放一起供大家参考:

  • HttpURLConnnection

image.png

  • OkHttp + Undertow

image.png


这里为大家准备了一份小小的礼物,关注公众号,输入如下代码,即可获得百度网盘地址,无套路领取!

001:《程序员必读书籍》
002:《从无到有搭建中小型互联网公司后台服务架构与运维架构》
003:《互联网企业高并发解决方案》
004:《互联网架构教学视频》
006:《SpringBoot实现点餐系统》
007:《SpringSecurity实战视频》
008:《Hadoop实战教学视频》
009:《腾讯2019Techo开发者大会PPT》

010: 微信交流群

image.png


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK