今天和大家聊一聊在Spring Cloud微服务框架实践中,比较核心但是又很容易把人搞得稀里糊涂的一个问题,那就是在Spring Cloud中Hystrix、Ribbon以及Feign它们三者之间在处理微服务调用超时从而触发熔断降级的关系是什么?
我们知道在Spring Cloud微服务体系下,微服务之间的互相调用可以通过Feign进行声明式调用,在这个服务调用过程中Feign会通过Ribbon从服务注册中心获取目标微服务的服务器地址列表,之后在网络请求的过程中Ribbon就会将请求以负载均衡的方式打到微服务的不同实例上,从而实现Spring Cloud微服务架构中最为关键的功能即服务发现及客户端负载均衡调用。
另一方面微服务在互相调用的过程中,为了防止某个微服务的故障消耗掉整个系统所有微服务的连接资源,所以在实施微服务调用的过程中我们会要求在调用方实施针对被调用微服务的熔断逻辑。而要实现这个逻辑场景在Spring Cloud微服务框架下我们是通过Hystrix这个框架来实现的。
调用方会针对被调用微服务设置调用超时时间,一旦超时就会进入熔断逻辑,而这个故障指标信息也会返回给Hystrix组件,Hystrix组件会根据熔断情况判断被调微服务的故障情况从而打开熔断器,之后所有针对该微服务的请求就会直接进入熔断逻辑,直到被调微服务故障恢复,Hystrix断路器关闭为止。
Hystrix、Feign及Ribbon的配置说明
接下来我们先来看看在Spring Cloud微服务系统中Hystrix、Feign及Ribbon的常用配置都有哪些以及它们的使用场景分别是什么?
Hystrix配置说明
在Spring Cloud微服务体系中Hystrix主要被用于实现实现微服务之间网络调用故障的熔断、过载保护及资源隔离等功能。而要正确使用Hystrix提供的这些功能就需要对Hystrix常用的配置有一定深入的了解,否则你会发现使用过程中认为一定会生效的配置常常不会起作用,接下来我们就按照参数配置的类型对Hystrix中的常见配置做一个梳理。
1)、线程隔离相关配置
Hystrix具备的重要关键特性之一就是它能够实现对第三方服务依赖的资源隔离,而隔离最常见的方式是通过线程池资源的隔离来实现的,Hystrix会为每个第三方服务依赖配置单独的线程池资源,从而避免对第三方服务依赖的请求占用应用主线程资源以免造成系统雪崩。Hystrix中关于线程隔离相关的配置如下:
2)、熔断器相关配置
熔断器是Hystrix最主要的功能,它开启和关闭的时机、灵敏度及准确性是Hystrix是否能够发挥重要的关键,而在Hystrix中与熔断器相关的几个配置如下:
3)、Metrics(统计器)相关配置
Hystrix是否正常工作最主要的依赖就是根据捕获的调用指标信息来判断是否打开或者关闭熔断器,而影响Hystrix行为很重要的因素就是以下Hystrix关于Metrics的配置。
在上述关于Metrics的配置中出现了两个比较频繁的概念:滑动窗口、桶,Hystrix的统计器就是由滑动窗口来实现的。关于滑动窗口举一个非常形象的例子,假设你坐在一辆大巴车的上,车窗外是一排排笔直的大树,车辆在高速地行驶着,大树迅速地从车窗滑过,如果用每棵树来代表一个网络请求,用大巴车的行驶代表时间的流逝。那么大巴车的窗口就是一个非常典型的滑动窗口,而你通过这个车窗能够看到的大树就是Hystrix要统计的数据。
桶(bucket)是Hystrix统计滑动窗口数据时的最小单位。同样以上面的例子为例,在大巴车行驶非常快的情况下,如果每掠过一棵树就统计一次窗口内大树的数据的话,会造成比较大的开销,而如果我们将车窗分成10份,大巴车行驶时每掠过窗口的1/10就统计一次数据,那么开销就会小很多了。所以,Hystrix中的桶就是滑动窗口1/N的概念。
4)、线程池相关配置
在前面提到过Hystrix实现对第三方服务依赖资源隔离最主要的方式就是通过线程池,而Hystrix内线程的使用是基于Java内置线程池的简单封装,通过以下Hystrix线程池参数我们可以控制执行Hystrix命令的线程池的行为。具体如下:
Ribbon配置说明
Ribbon在Spring Cloud中对于支持微服之间的通信发挥着非常关键的作用,其主要功能包括客户端负载均衡器及用于中间层通信的客户端。在基于Feign的微服务通信中无论是否开启Hystrix,Ribbon都是必不可少的,Ribbon的配置参数主要如下:
以上配置方式将对所有的微服务调用有效,如果想针对单独的微服务进行配置,使用“微服务名.ribbon”这样的配置方式即可,例如:
Feign配置说明
Feign是一款Java语言编写的HttpClient绑定器,在Spring Cloud微服务中用于实现微服务之间的声明式调用,Feign自身可以支持多种HttpClient工具包,例如OkHttp及Apache HttpClient,针对不同的HttpClient其默认常见配置如下:
Feign、Hystrix、Ribbon的超时配置关系
在前面的内容我们分别单独梳理了Feign、Hystrix及Ribbon三者常见的配置,针对各自的特性功能配置我们并没有异议,但是我们也看到它们都有针对微服务超时的配置,而在开启熔断器功能后,这些超时配置会影响到熔断器及服务降级逻辑的行为,那么它们之间超时的配置有什么关系呢?如下:
如上图所示,在Spring Cloud中使用Feign进行微服务调用分为两层:Ribbon的调用及Hystrix的调用。所以Feign的超时时间就是Ribbon和Hystrix超时时间的结合,而如果不启用Hystrix则Ribbon的超时时间就是Feign的超时时间配置,Feign自身的配置会被覆盖。
而如果开启了Hystrix,那么Ribbon的超时时间配置与Hystrix的超时时间配置则存在依赖关系,因为涉及到Ribbon的重试机制,所以一般情况下都是Ribbon的超时时间小于Hystrix的超时时间,否则会出现以下错误:
那么Ribbon和Hystrix的超时时间配置的关系具体是什么呢?如下:
而Ribbon的重试次数的计算方式为:
以上图中的Ribbon配置为例子,Ribbon的重试次数=1+(1+1+1)*(30000+10000),所以Hystrix的超时配置应该>=160000毫秒。在Ribbon超时但Hystrix没有超时的情况下,Ribbon便会采取重试机制;而重试期间如果时间超过了Hystrix的超时配置则会立即被熔断(fallback)。
如果不配置Ribbon的重试次数,则Ribbon默认会重试一次,加上第一次调用Ribbon的重试次数为2次,以上述配置为例Hystrix超时时间配置为2*40000=80000,由于很多情况下,大家一般不会主动配置Ribbon的重试次数,所以这里需要注意下!强调下,以上超时配置的值只是示范,超时配置有点大不太合适实际的线上场景,大家根据实际情况设置即可!
PS:以上整理应该是全网最全的一份,如果觉得有用辛苦转发下,给在使用Spring Cloud微服务的朋友们送去一点小温暖!^_^
参考资料:
https://github.com/Netflix/Hystrix/wiki/Configuration
https://github.com/Netflix/ribbon/wiki/Getting-Started
https://shihlei.iteye.com/blog/2435851
https://cloud.spring.io/spring-cloud-netflix/spring-cloud-netflix.html#_hystrix_timeouts_and_ribbon_clients
https://blog.csdn.net/east123321/article/details/82385816
推荐阅读:
Spring Cloud微服务运维神器之Consul Template?
Python写的微服务如何融入Spring Cloud体系?
Spring Cloud微服务中网关服务是如何实现的?(Zuul篇)
—————END—————
识别图片二维码,关注“无敌码农”获取精彩内容
本文分享自微信公众号 - 无敌码农(jiangqiaodege)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。