在将SpringCloud升级到3.0.X后,与前端对接接口时,接收到反馈说,经常会有接口超时的情况,(与前端约定了超时时间为5s),然后进行压测排查问题。
最初怀疑是不是代码质量问题,所以在SpringGateway的Filter,以及接口服务的代码中加上计时日志后,发现都是毫秒级别就处理完成的,不存在有效率问题的代码块;
既然不是代码质量问题,便怀疑是不是SpringGateway和微服务之间不是同一个服务器,服务器之间的网络通讯有问题,运维小伙伴排查一圈下来,网络也是没有问题的;
最后只能是又掉头回去查看日志,这次结合SpringGateway和微服务的日志一起分析,出现了一个疑点,反馈超时的时候,SpringGateway转发到微服务时,日志出现了断层,而且每次断层的时间间隔一模一样,正好是卡顿了5秒。
此时可以确定的是,Gateway在转发请求的时候,可能存在问题,第一反应就是,是不是SpringGateway的线程池是不是需要重新配置,所以先调整SpringGateway的线程池配置。
SpringGateway的线程池是通过配置netty来完成的,debug可以发现是使用ReactorResourceFactory进行管理的,然后通过ReactorResourceFactory的LoopResources进而确定具体线程数量,主要是修改reactor.netty.ioSelectCount和reactor.netty.ioWorkerCount参数值,reactor.netty.ioSelectCount默认是-1,reactor.netty.ioWorkerCount是cpu核心数,这里我们可以进行优化,具体如下:
@Configuration
public class ReactResourceFactoryConfiguration{
@Bean
public ReactorResourceFactory reactorResourceFactory() {
//配置select组参数reactor.netty.ioSelectCount
System.setProperty("reactor.netty.ioSelectCount", "1");
//配置工作线程参数reactor.netty.ioWorkerCount
//配置为cpu核心数的3倍并且最少4线程数测试
int ioWorkerCount = Math.max(Runtime.getRuntime().availableProcessors()*3, 4);
System.setProperty("reactor.netty.ioWorkerCount", String.valueOf(ioWorkerCount ));
return new ReactorResourceFactory();
}
}
重新压测后,发现在SpringGateway这里已经不再会有卡顿的情况了,但是仍然存在有接口卡顿的情况,通过对接口日志链一路排查,发现微服务间的feign调用,也会存在卡顿刚好5秒左右的问题,所以按照SpringGateway的思路来处理,配置openFeign的线程池,通过翻阅官网可以找到,可以将openFeign的默认线程替换ApacheHc5或者OkHttp,并且通过spring.cloud.openfeign.httpclient.hc5和spring.cloud.openfeign.httpclient.okhttp来配置相关参数,我们选择使用hc5线程池来测试,具体如下:
引入hc5依赖
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hc5</artifactId>
</dependency>
在配置文件添加相关参数启用hc5
spring.cloud.openfeign.httpclient.hc5.enabled=true
启用后,微服务会打印出线程池的相关日志:
重新测试接口后,发现不再有卡顿的现象出现了,至此优化结束。