背景:在一个以springcloud为基础架构的微服务项目中,活动期间并发量一大就会出现服务调用失败的问题。经定位发现,被调用服务中无对应的请求日志,继续通过日志查询确认是feign调用时出现服务降级,进入降级方法统一返回调用失败。通过jmeter做并发测试,并发量一到20问题就会复现。
我们知道,feign的调用链路中内置了hystrix逻辑,hystrix出现服务降级的情况有很多种,下图展示了服务降级的场景,从下图可知服务降级通常有三种原因。
第一,断路器是open状态,此时所有的请求会进入到降级方法中。我们项目的实际情况是活动启动的瞬间并发高导致降级,这种降级只是部分请求的降级,故排除这种情况。
第二,请求被调用服务异常或者超时。被调用服务未查到相关日志且通过数据中的网络监控网络连接也是正常的,故排除这种情况。
第三,线程池的线程数不够,大量请求来不及处理无可用资源进入降级逻辑。这种情况比较符合我们实际情况,可以继续排查。
通过进一步分析我们得知,默认的隔离策略是线程池隔离,且线程池核心线程数为10。
#模式配置
hystrix.command.default.execution.isolation.strategy = THREAD
进一步了解线程池的隔离策略和执行逻辑。
1.基于feign的服务调用时,以服务名作为key值,为该key值创建一个线程池,默认大小为10,各个服务名的线程池相互隔离。
2.线程池的执行逻辑同jdk的ThreadPoolExecutor
因此解决问题的关键是指定线程池核心线程数来应对并发需求,配置完成后可通过并发测试进行验证。
hystrix:
threadpool:
default:
#基于feign的服务调用,为每个服务(各个渠道)创建一个隔离的线程池,核心线程数为50.
coreSize: 50