|
|
|
|
移动端

:轻拢慢捻,谈微服务熔断大总管

本文来源:http://www.144865.com//

,

我这篇文章来的晚了些,因为hystrix已经进入维护模式。但已经有非常多的同学入坑了,那么本篇文章就是及时雨。本文将说明熔断使用的一些注意事项,可能会细的让你厌烦。

作者:小姐姐养的狗来源:小姐姐味道|2019-09-26 10:07

我这篇文章来的晚了些,因为hystrix已经进入维护模式。但已经有非常多的同学入坑了,那么本篇文章就是及时雨。本文将说明熔断使用的一些注意事项,可能会细的让你厌烦。

前半段,是理论部分,各种熔断都适用。后半段,是参数部分,适合微调。

那我们开始。

通常来说,皇帝在微服务里想夜生活过得舒服,能够大刀阔斧单刀直入,不因私事丢江山,就不得不靠熔断大总管。

时过境迁。提到熔断大总管就不得不说他手下最突出的三位公公:sentinel,或hystrix,也可能是resilience4j。

这三位都是解决一类问题的,如著名的雪崩:A→B→C互相依次调用,但C项目很可能出现问题(流量过大或者报错等),引发线程一直进行等待,导致拖垮整个链路层,线程资源耗尽。

一、背景

假如是用的spring全家桶系列,在接口调用上大多会走这个路线。我们这里依然是在说hystrix,虽然现在不再受宠。

Feign —-→

Hystrix —-→

Ribbon —-→

Http Client(apache http components/Okhttp)

具体如下图所示:

二、配置

首先来点理论性的东西。好吃不贵。

Ⅰ隔离方式

线程隔离(默认):使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列。这种方式需要为每个依赖的服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)

信号隔离:使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃改类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)

Ⅱ熔断

如果某个目标服务调用慢或者大量超时,则此时熔断该服务的调用,对于后续调用请求,不再继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转,则恢复调用。

这个过程,可以想象成保险丝的行为。

行为虽然简单,但需要调节的参数却非常多。

使用方式

1.引入依赖

  1. <dependency> 
  2.     <groupId>org.springframework.cloud</groupId> 
  3.     <artifactId>spring-cloud-starter-hystrix</artifactId> 
  4. </dependency> 

2.配置参数

  1. feign: 
  2.   hystrix: 
  3. #不配置或为false则不生效 
  4.     enabled: true 
  5. hystrix: 
  6.   command: 
  7.     default
  8.       execution: 
  9.         isolation
  10.           thread: 
  11. #若配置了重试则超时时间= (1 + MaxAutoRetries + MaxAutoRetriesNextServer) * ReadTimeout 
  12.             timeoutInMilliseconds: 60000 
  13.   threadpool: 
  14.     default
  15.       coreSize: 10 
  16.       maxQueueSize: 50 
  17.       queueSizeRejectionThreshold: 30 
  18.       keepAliveTimeMinutes: 3 

3.配置fallback

因业务处理不同,建议每个feign client使用不同的fallback

到此,hystrix已经可以走马上任,至于干活儿稳不稳那是后话。

4.配置的其他姿势

hystrix到任务后,发现有的服务接口1s内就完事儿 ,还有的5s到10几秒才堪堪返回。一刀切的配置已难以管理诸多服务&接口。

想必已经有人发现,之前配置中混进了奇怪的东西——default关键词。这是对全局配置,那么对应的肯定有局部的配置。

如:对服务的,对某个接口的…

  1. hystrix: 
  2.   command: 
  3.     default
  4.       execution: 
  5.         isolation
  6.           thread: 
  7.             timeoutInMilliseconds: 60000 
  8.   threadpool: 
  9. #全局配置 
  10.     default
  11.       coreSize: 10 
  12.       maxQueueSize: 50 
  13.       queueSizeRejectionThreshold: 30 
  14.       keepAliveTimeMinutes: 3 
  15. #对某个服务配置,写service-id 
  16.     base-rpc: 
  17.       coreSize: 10 
  18.       maxQueueSize: 30 
  19.       queueSizeRejectionThreshold: 20 
  20.       keepAliveTimeMinutes: 3 
  21. #对某个接口配置 
  22.     BaseApiClient#searchItemSkuList(PosSkuSearch): 
  23.       coreSize: 10 
  24.       maxQueueSize: 40 
  25.       queueSizeRejectionThreshold: 30 
  26.       keepAliveTimeMinutes: 1 

另外,还可以使用@HystrixCommand注解进行配置。

5.配置的动态修改

很多情况下,不能修改个配置,特别是临时修改配置就重启下服务,能动态刷新就最好了。

于是我们盯上了hystrix使用archaius管理配置的问题。

archaius是Netflix公司开源项目之一,基于java的配置管理类库,主要用于多配置存储的动态获取。

主要功能是对apache common configuration类库的扩展。在云平台开发中可以将其用作分布式配置管理依赖构件。同时,它有如下一些特性:

动态获取属性

高效和线程安全的配置操作

配置改变时提供回调机制

可以通过jmx操作配置

复合配置

说了这么多那该怎么整呢?以下就是简单的示例。

  1. /捞配置 
  2. AbstractConfiguration config = ConfigurationManager.getConfigInstance(); 
  3.  
  4. /提取关注的部分,比如hystrix.threadpool 
  5. Iterable<String> iterable = () -> config.getKeys("hystrix.threadpool"); 
  6. List<Property> result = StreamSupport.stream(iterable.spliterator(), false).map(t -> new Property(t, config.getString(t, ""))) 
  7.         .sorted(Comparator.comparing(Property::getName)).collect(Collectors.toList()); 
  8.  
  9. /修改配置 
  10. config.setProperty("hystrix.threadpool.base-rpc.coreSize", 20); 
  11.  
  12. /移除配置 
  13. config.clearProperty(hystrix.threadpool.base-rpc.coreSize"); 

三、其他参数

要是觉得hystrix这么听话,那就太小看它了。别忘了前面有feign,后面还有ribbon,再往后http client呢!一堆超时参数,当代的八门金锁阵

1.feign超时

  1. feign: 
  2.   hystrix: 
  3.     enabled: true 
  4.   client: 
  5.     config: 
  6.       default
  7.         connectTimeout: 5000 
  8.         readTimeout: 5000 
  9.       rpc-pos: 
  10.         connectTimeout: 5000 
  11.         readTimeout: 8000 
  12.       xx-rpc: 
  13.         connectTimeout: 5000 
  14.         readTimeout: 12000 
  15.       order-rpc: 
  16.         connectTimeout: 5000 
  17.         readTimeout: 8000 

feign是暴露给用户使用的,Spring在处理这一块的时候,会有意识地使用feign的超时时间来设置后面的ribbon 和http client组件。

2.ribbon超时

  1. #全局配置 
  2. ribbon: 
  3.   ReadTimeout: 60000 
  4.   ConnectTimeout: 10000 
  5.   #false to only allow get method to retry 
  6.   OkToRetryOnAllOperations: true 
  7.   # Max number of next servers to retry (excluding the first server) 
  8.   MaxAutoRetriesNextServer: 2 
  9.   # Max number of retries on the same server (excluding the first try) 
  10.   MaxAutoRetries: 0 
  11.   # Interval to refresh the server list from the source 
  12.   ServerListRefreshInterval: 5000 
  13.   retryableStatusCodes: 404,500 
  14. #服务配置 
  15. base-rpc: 
  16.   ribbon: 
  17.     ReadTimeout: 60000 
  18.     ConnectTimeout: 10000 
  19.     #false to only allow get method to retry 
  20.     OkToRetryOnAllOperations: true 
  21.     # Max number of next servers to retry (excluding the first server) 
  22.     MaxAutoRetriesNextServer: 2 
  23.     # Max number of retries on the same server (excluding the first try) 
  24.     MaxAutoRetries: 0 
  25.     # Interval to refresh the server list from the source 
  26.     ServerListRefreshInterval: 5000 
  27.     retryableStatusCodes: 404,500 

当feign设置了超时时间,Ribbon会依据feign的设置同步。Ribbon的这个超时时间,用于指导真正调用接口时,设置真正实现者的超时时间。

httpclient超时

  1. feign: 
  2.   hystrix: 
  3.     enabled: true 
  4.   ok 
  5.     enabled: true 
  6.   httpclient: 
  7.     enabled: false 
  8. /连接池最大连接数,默认200 
  9.     max-connections: 500 
  10. /每一个IP最大占用多少连接 默认 50 
  11.     max-connections-per-route: 50 
  12. /默认连接超时时间:2000毫秒 
  13.     connection-timeout: 8000 
  14. /连接池管理定时器执行频率:默认 3000毫秒 
  15.     connection-timer-repeat: 6000 
  16. /连接池中存活时间,默认为5 
  17.     time-to-live: 5 
  18.     time-to-live-unit: minutes 

超时设置遵循的基本原则是:依赖方的超时配置覆盖被依赖方的配置,而其配置覆盖的形式,则是使用的Spring Boot 的 AutoConfiguration 机制实现的

如:若开启feign.okhttp.enabled=true,则okhttp的超时时间是feign.httpclient.connectionTimeout的值,默认2000毫秒

总结:超时——还是 feign 说了算!

四、hystrix dashboard

能够将这些状态可视化,是非常棒的,需要引入一个jar包。

  1. <dependency> 
  2.     <groupId>org.springframework.cloud</groupId> 
  3.     <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> 
  4. </dependency> 

下面这张图,就是针对后台监控的一些解释。

 (图片来自网络)

附:配置参数说明

一、Command Properties

以下属性控制HystrixCommand,前缀hystrix.command.default

1、Execution

以下属性控制HystrixCommand.run()如何执行。

比较重要的参数,有:

execution.isolation.strategy

execution.isolation.thread.timeoutInMilliseconds

2、Fallback

以下属性控制HystrixCommand.getFallback()如何执行。这些属性适用于ExecutionIsolationStrategy.THREAD和ExecutionIsolationStrategy.SEMAPHORE。

3、Circuit Breaker

断路器属性控制HystrixCircuitBreaker。

4、Metrics

以下属性与从HystrixCommand和HystrixObservableCommand执行捕获指标有关。

5、Request Context

这些属性涉及HystrixCommand使用的HystrixRequestContext功能

二、Command Properties

下列属性控制HystrixCollapser行为。前缀:hystrix.collapser.default

三、ThreadPool Properties

以下属性控制Hystrix命令在其上执行的线程池的行为。

大多数时候,默认值为10的线程会很好(通常可以做得更小)前缀:hystrix.threadpool.default 。


【编辑推荐】

  1. 微服务架构之–消息队列Kafka图解最全知识点
  2. 一篇文章读懂 Python 多线程
  3. 从单体式架构迁移到微服务架构:三个策略叙述
  4. 亿级规模的高可用微服务系统,如何轻松设计?
  5. 微服务架构下,MySQL读写分离后,Druid连接池参数优化实战
【责任编辑:武晓燕 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

用Python玩转excel

用Python玩转excel

让重复操作傻瓜化
共3章 | DE8UG

166人订阅学习

AI入门级算法

AI入门级算法

算法常识
共22章 | 周萝卜123

138人订阅学习

这就是5G

这就是5G

5G那些事儿
共15章 | armmay

128人订阅学习

视频课程+更多

你必学的SSM实战案例

你必学的SSM实战案例

讲师:齐毅19680人学习过

2019新版HCNP|HCIP-R&S|CCNP

2019新版HCNP|HCIP-R&S|CCNP

讲师:郝旺5051人学习过

Vue.js 2.0之全家桶系列视频课程(vue、vue-router、axios、vuex)

Vue.js 2.0之全家桶系列视频课程(vue、vue-r

讲师:汤小洋1454934人学习过

读 书 +更多

游戏开发核心技术--剧本和角色创造

《游戏开发核心技术--剧本和角色创造》分“剧本”、“角色”和“游戏玩法”三部分,第一部分着重说明故事的历史、一般故事元素、传统故事设...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微

申博会员登录 申博游戏登入不了 www.99msc.com www.1111msc.com 申博娱乐网址 申博支付宝充值
菲律宾申博游戏登入 菲律宾申博太阳城登入 金太阳国际娱乐网址 申博代理登录 申博真人官网登入 太阳城申博开户登入
菲律宾申博官方网址登入 申博娱乐太阳成登入 菲律宾申博太阳网上娱乐99 申博注册登入 www.988msc.com 申博太阳城娱乐中心直营网