每日一博 | Spring Cloud Hystrix 熔断
一、什么是熔断
在一个家庭中有各种各样的家电,我们假设每个家电都没有保险丝,一旦有一天某个家电出现短路,造成整个电路短路然后很有可能就把整个家庭的电器及电路给烧坏了。但如果每个家电入口线路都有一个保险丝(断路器),那么不管那个家电发生短路这个家电的保险丝就会快速熔断(断开电路),从而保护了整个电路及电路上其它的家电的正常运行。
软件行业里面的熔断机制与这个一致,在整个微服务集群中,由于其中一个或者几个微服务出现故障或堵塞,若没有快速的熔断机制,就会造成整个微服务集群的拥堵最终整个微服务出现雪崩被拖死。熔断机制的核心机制就是在确保某个微服务出现故障的时候实现快速熔断(断路)或者服务降级快速失败,避免拥堵。从而保证其它业务其它服务的正常运行。
二、Hystrix 设计原则
- 防止单个服务的故障,耗尽整个系统服务的容器(比如tomcat)的线程资源,避免分布式环境里大量级联失败。通过第三方客户端访问(通常是通过网络)依赖服务出现失败、拒绝、超时或短路时执行回退逻辑。
- 用快速失败代替排队(每个依赖服务维护一个小的线程池或信号量,当线程池满或信号量满,会立即拒绝服务而不会排队等待)和优雅的服务降级;当依赖服务失效后又恢复正常,快速恢复。
- 提供接近实时的监控和警报,从而能够快速发现故障和修复。监控信息包括请求成功,失败(客户端抛出的异常),超时和线程拒绝。如果访问依赖服务的错误百分比超过阈值,断路器会跳闸,此时服务会在一段时间内停止对特定服务的所有请求。
- 将所有请求外部系统(或请求依赖服务)封装到HystrixCommand或HystrixObservableCommand对象中,然后这些请求在一个独立的线程中执行。使用隔离技术来限制任何一个依赖的失败对系统的影响。每个依赖服务维护一个小的线程池(或信号量),当线程池满或信号量满,会立即拒绝服务而不会排队等待。
三、Hystrix特性
- 请求熔断: 当Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open). 这时所有请求会直接失败而不会发送到后端服务. 断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN)。这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN). Hystrix的断路器就像我们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量, 并且断路器有自我检测并恢复的能力。
- 服务降级:Fallback相当于是降级操作. 对于查询操作, 我们可以实现一个fallback方法, 当请求后端服务出现异常的时候, 可以使用fallback方法返回的值. fallback方法的返回值一般是设置的默认值或者来自缓存。
-
依赖隔离(采用舱壁模式,Docker就是舱壁模式的一种):在Hystrix中, 主要通过线程池来实现资源隔离. 通常在使用的时候我们会根据调用的远程服务划分出多个线程池.比如说,一个服务调用另外两个服务,你如果调用两个服务都用一个线程池,那么如果一个服务卡在哪里,资源没被释放后面的请求又来了,导致后面的请求都卡在哪里等待,导致你依赖的A服务把你卡在哪里,耗尽了资源,也导致了你另外一个B服务也不可用了。这时如果依赖隔离,某一个服务调用A B两个服务,如果这时我有100个线程可用,我给A服务分配50个,给B服务分配50个,这样就算A服务挂了,我的B服务依然可以用。
- 请求缓存:比如一个请求过来请求我userId=1的数据,你后面的请求也过来请求同样的数据,这时我不会继续走原来的那条请求链路了,而是把第一次请求缓存过了,把第一次的请求结果返回给后面的请求(参考@CacheResult、@CacheKey、@CacheRemove注解)。
- 请求合并:我依赖于某一个服务,我要调用N次,比如说查数据库的时候,我发了N条请求发了N条SQL然后拿到一堆结果,这时候我们可以把多个请求合并成一个请求,发送一个查询多条数据的SQL的请求,这样我们只需查询一次数据库,提升了效率。
在Hystrix 中我们用的比较多的是前三点,后面两点并不适用于所有业务。
四、实战
1、添加依赖
添加 `spring-cloud-starter-hystrix`模块,实际使用过程中我们使用了Feign后已经包含了Hystrix模块及Ribbon模块,不需要单独引入。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
2、开启Hystrix
在启动类中加入@EnableCircuitBreaker注解,表示允许断路器。如下代码所示:
//允许断路器 @EnableCircuitBreaker public class Application { ... }
在spring cloud 项目中使用 `@SpringCloudApplication` 注解后已经包含了`@EnableCircuitBreaker` 注解及其它微服务注解,看源码:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public @interface SpringCloudApplication { }
3、方法级熔断
Spring cloud 采用http进行通讯,spring cloud 结合Eureka针对http请求响应操作做了封装,支持两种方式,RestTemplate 及 Feign 模式,Feign模式参考其它章节,这里简单介绍RestTemplate模式。
@Service public class HelloService { @Autowired private RestTemplate restTemplate; //请求熔断注解,当服务出现问题时候会执行fallbackMetho属性的名为helloFallBack的方法 @HystrixCommand(fallbackMethod = "helloFallBack") public String helloService() throws ExecutionException, InterruptedException { return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody(); } public String helloFallBack(){ return "error"; } }
这是一个外部服务调用的restTemplate实现,通过 @HystrixCommand(fallbackMethod = "helloFallBack") 标志这个方法开启熔断机制, 指定熔断后服务降级方法为:helloFallBack()。此时若被调用方异常,接下来请求都会进入服务降级实现(回调方法)并快速失败。@HystrixCommand 也可以指定其它配置:
public @interface HystrixCommand { String groupKey() default ""; String commandKey() default ""; String threadPoolKey() default ""; String fallbackMethod() default ""; HystrixProperty[] commandProperties() default {}; HystrixProperty[] threadPoolProperties() default {}; Class<? extends Throwable>[] ignoreExceptions() default {}; ObservableExecutionMode observableExecutionMode() default ObservableExecutionMode.EAGER; HystrixException[] raiseHystrixExceptions() default {}; String defaultFallback() default ""; }
让我们来逐个介绍下@HystrixCommand注解的各个参数:
- commandKey:配置全局唯一标识服务的名称,比如,库存系统有一个获取库存服务,那么就可以为这个服务起一个名字来唯一识别该服务,如果不配置,则默认是@HystrixCommand注解修饰的函数的函数名。
- groupKey:一个比较重要的注解,配置全局唯一标识服务分组的名称,比如,库存系统就是一个服务分组。通过设置分组,Hystrix会根据组来组织和统计命令的告、仪表盘等信息。Hystrix命令默认的线程划分也是根据命令组来实现。默认情况下,Hystrix会让相同组名的命令使用同一个线程池,所以我们需要在创建Hystrix命令时为其指定命令组来实现默认的线程池划分。此外,Hystrix还提供了通过设置threadPoolKey来对线程池进行设置。建议最好设置该参数,使用threadPoolKey来控制线程池组。
- threadPoolKey:对线程池进行设定,细粒度的配置,相当于对单个服务的线程池信息进行设置,也可多个服务设置同一个threadPoolKey构成线程组。
- fallbackMethod:@HystrixCommand注解修饰的函数的回调函数,@HystrixCommand修饰的函数必须和这个回调函数定义在同一个类中,因为定义在了同一个类中,所以fackback method可以是public/private均可。
- commandProperties:配置该命令的一些参数,如executionIsolationStrategy配置执行隔离策略,默认是使用线程隔离,此处我们配置为THREAD,即线程池隔离。参见:com.netflix.hystrix.HystrixCommandProperties中各个参数的定义。
- threadPoolProperties:线程池相关参数设置,具体可以设置哪些参数请见:com.netflix.hystrix.HystrixThreadPoolProperties
- ignoreExceptions:调用服务时,除了HystrixBadRequestException之外,其他@HystrixCommand修饰的函数抛出的异常均会被Hystrix认为命令执行失败而触发服务降级的处理逻辑(调用fallbackMethod指定的回调函数),所以当需要在命令执行中抛出不触发降级的异常时来使用它,通过这个参数指定,哪些异常抛出时不触发降级(不去调用fallbackMethod),而是将异常向上抛出。
- observableExecutionMode:定义hystrix observable command的模式;
- raiseHystrixExceptions:任何不可忽略的异常都包含在HystrixRuntimeException中;
- defaultFallback:默认的回调函数,该函数的函数体不能有入参,返回值类型与@HystrixCommand修饰的函数体的返回值一致。如果指定了fallbackMethod,则fallbackMethod优先级更高。
给个例子:
@HystrixCommand(commandKey = "testCommand", groupKey = "testGroup", threadPoolKey = "testThreadKey", fallbackMethod = "hiConsumerFallBack", ignoreExceptions = {NullPointerException.class}, threadPoolProperties = { @HystrixProperty(name = "coreSize", value = "30"), @HystrixProperty(name = "maxQueueSize", value = "101"), @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"), @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"), @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"), @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1440") } )
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
OSChina 周一乱弹 —— 带这么多钱,你要泡我吗
Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @tom_tdhzz :白给?#今日歌曲推荐# 分享Lana Del Rey的单曲《Yayo》: 《Yayo》- Lana Del Rey 手机党少年们想听歌,请使劲儿戳(这里) @红薯 :沐是洗头,浴是洗身子 别假装自己爱洗澡了, 从小就不喜欢洗澡的你, “没有人可以9你 但是未来有很多人可以996你。” 洗澡的时候顺便把钱洗了, @我想有个家 :一不留神,洗了这么多钱 洗澡还带这么多钱, 你是去洗澡么? 是不是有什么预谋, “带这么多钱,你要泡我吗?” 泡你, 是不是要买身合适的衣服? 我看优衣库就很好。 @蓝瞳 :优衣库是年轻人年轻情侣的地盘,大叔的俺都不好意思跟他们一起选衣服 没关系呀, 优衣库也有大叔穿的衣服, 给你挑挑去, “呃,复古款式,适合大叔穿。” 有些衣服就不太好意思穿出门, 但有好意思穿的。 @开源中国首席屌炸天 :网友说小姑凉本来不太好意思穿公主裙去电影院,结果她亲叔特别好意思的陪她一起穿了。。。 看完感觉再也不能直视《魔发公主》了。 @打飞机的猪猪侠 :单身久了 看动画片里面的女人。都觉得真特么的漂亮 想给...
- 下一篇
微软对 Chromium 新贡献:为 HTML 元素引入更现代化样式
基于 Chromium 的 Edge 浏览器在近期的更新中相关功能得到不断增强,微软也正着手为用户带来更丰富的改进,其中就包括为 HTML 元素引入更现代化的样式,并使其默认启用。 一周前微软提交的 Commit 中,在使用全新设计的控件 UI 时候为 HTML 元素添加支持调整默认样式的功能。本次更新在启用 FormControlsRefresh 的时候还会更新文本相关类型的 UI。FormControlsRefresh 的部署和现代化默认样式将会在 Chromium 浏览器中让基础 HTML 元素更加现代化。 根据 Commit,微软希望更新 UI 以输入 type=range。微软表示当 FormControlsRefresh 功能启用的时候,新 UI 通过扩展 NativeThemeAura 以覆盖 NativeThemeBase 提供的当前样式而实现。新设计需要绘制滑块轨道的选定值部分,添加附加代码以在滑块拇指位置更改时使滑块轨道的布局无效。 来源:cnBeta
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Mario游戏-低调大师作品
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8编译安装MySQL8.0.19
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7