1、断路器

  在消费服务的启动类,添加注解:@EnableCircuitBreaker,在消费服务的调用类上,添加注解:@HystrixCommand(fallbackMethod = "") -> 失败了调的方法。(熔断超时默认 2s )

  当被调用的服务,超时或者未反应/down掉,就会触发熔断请求,返回定义的逻辑。

  工作流程:

  1)、加注解:@HystrixCommand 或 @HystrixObservableCommand ,前者用于依赖的服务返回单个操作结果的时候,后者用于依赖的服务返回多个操作结果的时候。(具体的实现看书籍)

  命令模式,将客户端请求封装为一个对象,能让不同的请求对客户端进行参数化。(让不同类型的参数,都可以请求)

  2)、命令执行:

  HystrixCommand 实现了 execute()、queue() 执行方法。

  execute():同步执行,从依赖的服务返回一个单一的结果对象,或错误时抛出异常,R value = command.execute();

  queue():异步执行,直接返回一个 Future 对象,其中包含了服务执行结束时返回的单一结果对象,Future<R> fValue = command.queue();

  HystrixObservableCommand 实现了 observe()、toObservable() 执行方法。

  Observable<R> obValue = command.observe(),代表操作了多个结果,返回 HotObservanle;

  Observable<R> ocValue = command.toObservable(),也代表操作了多个结果,返回 Cold Observable;

  Hystrix 底层实现了大量的 RxJava,RxJava 的观察者-订阅者模式。

  Observable 向订阅者 Subscriber 对象发布事件(即异服务调用),一个Observable 可以发出多个事件,直到结束或者发生异常。每发出一个事件,就会调用对应观察者 Subscriber.onNext() 方法。最后一定会调用 Subscriber.onCompleted() 或者 Subscriber.onError() 结束该时间的操作流。

  3)、结果是否被缓存:当命令的请求缓存功能开启,命令缓存命中,缓存的结果就会以 Observable 对象的形式返回。

  4)、断路器是否打开: - 断路器是否已经开始运行

  命令结果没有命中缓存中,如果断路器打开,Hystrix 不会执行命令,而是转到 fallback 处理逻辑。如果断路器关闭,则继续执行。

  5)、线程池/请求队列/信号量是否占满: - 线程太多

  如果与命令相关的线程池或请求队列或者信号量已经占满,则 Hystrix 也不会执行命令,而是转接到 fallback 处理逻辑。

  该线程池并非容易的线程池,而是每个依赖服务的专有线程池。

  6)、请求依赖服务:

  HystrixObserveableCommand.construct() 或 HystrixCommand.run(),决定了采取什么样的方式去请求依赖服务。

  第一种返回一个 Observable 对象来发射多个结果,或通过 onError 发送错误通知;

  第二种返回一个单一的结果,或者抛出异常。

  超时也会转到 fallback 处理逻辑。

  7)、计算断路器的健康度: - 服务调用失败/超时等超过设置

  Hystrix 会将成功、失败、拒绝、超时等信息报告给断路器,断路器会维护一组计数器来统计这些数据。根据数据值,来对某个依赖服务的请求进行 "熔断/短路",直到恢复期结束。在恢复期结束后,再根据统计数据判断是否还是未达到健康指标,或再次"熔断/短路"。

  8)、fallback 处理:- 回退 - 服务降级

  当命令执行失败的时候,Hystrix 会进入 fallback 尝试回退处理,该操作叫做 "服务降级"。

  第4、5、6步都可能会引起服务降级。

  最终的降级逻辑一定不是一个依赖网络请求的处理,而是一个能够稳定返回结果的处理逻辑。

  HystrixCommand.getFallback() 来实现服务降级;

  HystrixObservableCommand.resumeWithFallback() 来实现降级逻辑。

  9)、返回成功的响应:

2、断路器原理

  HystrixCricuitBreaker 接口:

  allowRequest:每个 hystrix 命令的请求都通过它判断是否被执行;

  isOpen:返回当前断路器是否打开;

  markSuccess():用来闭合断路器,并重置度量指标对象。

  HystrixCricuitBreakImpl 是实现类,有几个重要核心对象,一个是 HystrixCommand 实例的属性对象,一个是记录各个度量指标的对象,一个是断路器是否打开的标志,一个是断路器打开或上一次测试的时间戳。

  断路器从关闭到打开(默认时间窗10s的请求信息快照):

  1)、请求总数 QPS 在预设的阈值范围内就返回 false,表示断路器还是关闭。阈值默认值20。

  2)、错误百分比在阈值范围内就返回 false,表示断路器还是关闭。默认是50。

  3)、以上两个条件都不满足,断路器就设置为打开状态(熔断/短路)。如果是从关闭状态切到打开状态,就将当前时间记录到上面的时间戳对象中。

  allowSingleTest() 为断路器再设置一个休眠时间(默认5s),在该休眠时间达到只有,再次允许请求尝试访问。若请求再次失败,断路器又进入打开状态。请求成功,则是关闭状态。

  所以 allowSingleTest() 与 isOpen() 方法的配合,实现了断路器的打开和关闭状态的切换。

3、依赖隔离

  会为每个依赖服务创建一个独立的线程池,这样就算某个依赖服务出现问题后,也只对该依赖服务的调用产生影响,不影响其他依赖服务。

  特点:

  依赖的服务从失效恢复正常后,它的线程池会被清理并且能够马上恢复健康服务。容器级别的清理 恢复速度慢的多;

  当依赖的服务出现配置错误的时候,线程池会被快速反映出此问题(失败、延迟、超时、拒绝等增加情况)。

  线程池的开销在设计的时候做过实验,消耗相对于来说是微乎其微的。对于某些需求来说,如果该消耗觉得很大,又用了信号量来优化。

  信号量控制单个依赖服务的并发量,但是不能设置超时和实现异步访问。线程池和信号量可以切换。

  在降级逻辑,Hystrix 尝试降级逻辑时,会在调用线程中使用信号量。或者命令执行。

4、使用详解

  1)、创建请求命令

  可以用继承 HystrixCommand 或者 @HystrixCommand 来实现熔断,注解添加在异服务之间调用的接口上。

  并且该注解可以实现 同步/异步 的操作。异步用 Future<T> 接收返回参数。

  2)、定义服务降级

  fallback 是 Hystrix 命令执行失败后使用的后备办法,实现服务的降级处理逻辑。

  继承方式的话,用重载 getFallback() 方法来实现降级处理;

  注解方式 @HystrixCommand(fallbackMethod = "failMethod") ,定义一个 faliMethod 方法,作为降级处理。(在同一个类中)

  3)、异常处理

  当服务调用发生异常,除了 HystrixBadRequestException 之外,其他异常都会被 Hystrix 认为命令执行失败,并触发服务降级的处理逻辑。

  使用注解 @HystrixCommand(ignoreExceptions = {XXException.class}) 可以忽略指定异常类型。当遇到该类型的异常时,就会被包装 HystrixBadRequestException 异常抛出,而不会触发降级的处理逻辑。

  4)、异常获取

  异常获取到后,可以根据不同的异常判断,做出不同的处理方式。直接在 fallback() 方法里定义一个 Throwable e ,就可以获取触发降级的具体异常内容。(e.getMessage())

  5)、命令名称、分组以及线程池划分

  Hystrix 会让相同组名的命令使用同一个线程池。所以创建 Hystrix 命令时,为其制定命令组名来实现默认的线程池划分。(还提供了 HystrixThreadPoolKey 来对线程池进行设置,进行更加细粒度的线程池划分,实际情况通常使用这一种划分方式)

  注解方式实现:@HystrixCommand(commandKey="getUserById",groupKey="UserGroup",ThreadPoolKey="getUserByIdThread")

  6)、请求缓存

  开启请求缓存功能:继承方式,重载 getCacheKey() 方式来开启请求缓存。

  好处:

  减少重复请求数,降低依赖服务的并发度(降低压力);

  在同一用户请求的上下文中,相同依赖服务的返回数据一致;

  请求缓存在 run() 和 construct() 执行之前生效,可以减少不必要的线程开销;

  清理失效缓存功能:通过 HystrixRequestCache.clear() 方法来进行缓存的清理,在做更新操作时,就将缓存清理掉。

  注解方式:@CacheResult 标记请求命令返回的结果应该被缓存,必须和 @HystrixCommand 结合使用;

  @CacheRemove 让请求命令的缓存失效,失效的缓存是根据 key 来的。(commandKey)

  @CacheKey 给参数添加标记,使之成为缓存的 key。

  7)、请求合并

  远程调用最常见的问题就是 通信消耗和连接总数。Hystrix 提供了 HystrixCollapser 来实现请求的合并,以减少通信消耗和线程池的占用。

  HystrixCollapser 实现了 在 @HystrixCommand 之前放置了一个合并处理器,将处于一个很短时间内(默认10ms)对同一依赖服务的多个请求进行整合并以批量方式发起请求。

SpringCloud(三)之我学 Hystrix的更多相关文章

  1. 玩转SpringCloud(F版本) 三.断路器(Hystrix)RestTemplate+Ribbon和Feign两种方式

    此文章基于: 玩转SpringCloud 一.服务的注册与发现(Eureka) 玩转SpringCloud 二.服务消费者(1)ribbon+restTemplate 转SpringCloud 二.服 ...

  2. SpringCloud 在Feign上使用Hystrix(断路由)

    SpringCloud  在Feign上使用Hystrix(断路由) 第一步:由于Feign的起步依赖中已经引入了Hystrix的依赖,所以只需要开启Hystrix的功能,在properties文件中 ...

  3. 三个层面学playbook(核心)

    三个层面学playbook(核心) ansible-playbook是ansible工具中的核心,对比ad-hoc(ansible)命令,可以把playbook理解为一系列动作的组成,结果传递.判断等 ...

  4. SpringCloud学习笔记(5):Hystrix Dashboard可视化监控数据

    简介 上篇文章中讲了使用Hystrix实现容错,除此之外,Hystrix还提供了近乎实时的监控.本文将介绍如何进行服务监控以及使用Hystrix Dashboard来让监控数据图形化. 项目介绍 sc ...

  5. springcloud费话之断路器(hystrix in feign)

    目录: springcloud费话之Eureka基础 springcloud费话之Eureka集群 springcloud费话之Eureka服务访问(restTemplate) springcloud ...

  6. 每天学点SpringCloud(十一):Hystrix仪表盘

    在SpringCloud学习系列博客第六篇文章中,我们已经学习了Hystrix的使用,但是那篇文章中有一点遗漏没有讲,那就是Hystrix Dashboard ,它可以实时的监控Hystrix的运行情 ...

  7. 每天学点SpringCloud(六):Hystrix使用

    Hystrix是一个实现断路器模式的库.什么是断路器模式呢?就像我们家庭中的电闸一样,如果有那一处出现意外,那么电闸就会立刻跳闸来防止因为这一处意外而引起更大的事故,直到我们确认处理完那一处意外后才可 ...

  8. SpringCloud学习系列之三----- 断路器(Hystrix)和断路器监控(Dashboard)

    前言 本篇主要介绍的是SpringCloud中的断路器(Hystrix)和断路器指标看板(Dashboard)的相关使用知识. SpringCloud Hystrix Hystrix 介绍 Netfl ...

  9. SpringCloud IDEA 教学 (四) 断路器(Hystrix)

    写在开始 在SpringCloud项目中,服务之间相互调用(RPC Remote Procedure Call —远程过程调用),处于调用链路底层的服务产生不可用情况时,请求会产生堆积使得服务器线程阻 ...

随机推荐

  1. 使用pyecharts绘制词云图-淘宝商品评论展示

    一.什么是词云图? 词云图是一种用来展现高频关键词的可视化表达,通过文字.色彩.图形的搭配,产生有冲击力地视觉效果,而且能够传达有价值的信息. 制作词云图的网站有很多,简单方便,适合小批量操作. BI ...

  2. seldom之数据驱动

    seldom之数据驱动 如果自动化某个功能,测试数据不一样而操作步骤是一样的,那么就可以使用参数化来节省测试代码. seldom是我在维护一个Web UI自动化测试框,这里跟大家分享seldom参数化 ...

  3. EPX Studio开发平台简介

    大家问我最多的问题就是“EPX 是什么?”“EPX 能够用来做什么?”“EPX 有什么优势?”“EPX 与其它开发平台的区别是什么?” 问题林林总总,总也回答不完,希望通过正文前面的这段文字,来简要回 ...

  4. Andorid 添加MenuPopup

  5. Java容器的常见问题

    记录Java容器中的常见概念和原理 参考: https://github.com/wangzhiwubigdata/God-Of-BigData#三Java并发容器 https://blog.csdn ...

  6. servlet本质是什么

    作者:Javdroider Hong链接:https://www.zhihu.com/question/21416727/answer/339012081来源:知乎著作权归作者所有.商业转载请联系作者 ...

  7. 简易版cnlog

    目录 简易版cnlog html文件 mycess.cess 页面效果 简易版cnlog 注意的点 1.一定先分好块标签,再基于一个个块标签进行装饰(相当于给一个个人化妆) 2.浮动: 我的理解是从一 ...

  8. openfire广播broadcast插件怎么发送消息给所有用户(包括在线和离线)

    openfire广播broadcast插件怎么发送消息给所有用户(包括在线和离线): 打开openfire管理界面,找到服务器系统属性,添加一个属性(属性名:plugin.broadcast.all2 ...

  9. 如何删除Python中文本文件的文件内容?

    在python中: open('file.txt', 'w').close() 或者,如果你已经打开了一个文件: f = open('file.txt', 'r+') f.truncate(0) # ...

  10. coding++ :Layui-监听事件

    在使用layui的form表单做验证提交的时候,如果结合vue,或者是三级联动的时候,就需要做事件监听了. 具体语法: form.on('event(过滤器值)', callback); 可以用于监听 ...