『互联网架构』软件架构-实战Hystrix实战(96)

时间:2022-06-25
本文章向大家介绍『互联网架构』软件架构-实战Hystrix实战(96),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

(一)Hystrix 介绍

  • 官网

https://github.com/Netflix/Hystrix

  • 学习直接看

https://github.com/Netflix/Hystrix/wiki

(二)Hystrix 降级,超时

  • 引入Springcloud Hystrix依赖,

一定要记住谁调用在谁哪里做处理,而不是被调用方,被调用方服务都挂了,你写降级有什么用?

    <dependency>      <groupId>org.springframework.cloud</groupId>      <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>    </dependency>
  • Hystrix是怎么做到降级的

通过一种叫做“命令模式”的方式,继承(HystrixCommand类)来包裹具体的服务调用 逻辑(run方法), 并在命令模式中添加了服务调用失败后的降级逻辑(getFallback),见 (OrderServiceCommand类) 源码:06-ms-consumer-order-ribbon-hystrix-customizing 通过配置类的方式

用Hystrix的注解@HystrixCommand可以更简单的实现上面的降级逻辑 直接在接口调用方的方法上增加注解@HystrixCommand(fallbackMethod = "findByIdFallback") 注解的源码:06-ms-consumer-order-ribbon-hystrix-fallback

  • 超时回退

在用户微服务工程里将UserController的findById接口增加执行等待时间,让该接口的执行时间变长,Hystrix调用接口默认两秒超时,超时后会自动执行降级方法。注解的源码:06-ms-provider-user

  • 启动流程06的源码

provider-user,consumber-order,eureka-server 必须都需要启动

(三)Hystrix 熔断,限流

  • 熔断怎么实现

源码:06-ms-consumer-order-ribbon-hystrix-fusing 06-ms-provider-user 里将UserController的findById接口增加模拟报错代码

测试报错和正常的情况,我们可以看到当报错达到一定阈值时,会自动熔断,阈值可以配置# 一个rolling window内最小的请求数。如果设为20,那么当一个rolling window的时间内(比如说1个rolling window是10秒)收到19个请求,即使19个请求都失败,也不会触发circuit break。默认20hystrix.command.default.circuitBreaker.requestVolumeThreshold# 触发短路的时间值,当该值设为5000时,则当触发circuit break后的5000毫秒内都会拒绝request,也就是5000毫秒后才会关闭circuit。默认5000hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds

(四)熔断器原理

熔断器模式定义了熔断器开关相互转换的逻辑

服务的健康状况 = 请求失败数 / 请求总数。熔断器开关由关闭到打开的状态转换是通过当前服务健康状况和设定阈值比较决定的.

  1. 当熔断器开关关闭时, 请求被允许通过熔断器. 如果当前健康状况高于设定阈值, 开关继续保持关闭. 如果当前健康状况低于设定阈值, 开关则切换为打开状态。
  2. 当熔断器开关打开时, 请求被禁止通过。
  3. 当熔断器开关处于打开状态, 经过一段时间后, 熔断器会自动进入半开状态, 这时熔断器只允许一个请求通过. 当该请求调用成功时, 熔断器恢复到关闭状态. 若该请求失败, 熔断器继续保持打开状态, 接下来的请求被禁止通过. 熔断器的开关能保证服务调用者在调用异常服务时, 快速返回结果, 避免大量的同步等待。并且熔断器能在一段时间后继续侦测请求执行结果, 提供恢复服务调用的可能。

(五)限流,线程资源隔离

源码:06-ms-consumer-order-ribbon-hystrix-threadisolation在用户微服务工程(06-ms-provider-user)里将UserController的findById接口模拟执行等待的代码。

在订单微服务工程(06-ms-consumer-order-ribbon-hystrix-thread-isolation)中修改接口超时配置为20秒。

用注解配置线程池大小

  1. CommandGroupKey:配置全局唯一标识服务分组的名称,比如,库存系统就是一个服务分组。当我们监控时,相同分组的服务会聚合在一起,必填选项。
  2. CommandKey:配置全局唯一标识服务的名称,比如,库存系统有一个获取库存服务,那么就可以为这个服务起一个名字来唯一识别该服务,如果不配置,则默认是简单类名。
  3. ThreadPoolKey:配置全局唯一标识线程池的名称,相同线程池名称的线程池是同一个,果不配置,则默认是分组名,此名字也是线程池中线程名字的前缀。
  4. ThreadPoolProperties:配置线程池参数,coreSize配置核心线程池大小和线程池最大大小,keepAliveTimeMinutes是线程池中空闲线程生存时间(如果不进行动态配置,那么是有任何作用的),maxQueueSize配置线程池队列最大大小,queueSizeRejectionThreshold限定当前队列大小,即实际队列大小由这个参数决定,通改变queueSizeRejectionThreshold可以实现动态队列大小调整。
  5. CommandProperties:配置该命令的一些参数,如executionIsolationStrategy配置执行离策略,默认是使用线程隔离,此处我们配置为THREAD,即线程池隔离。

此处可以粗粒度实现隔离,也可以细粒度实现隔离,如下所示。服务分组+线程池

粗粒度实现,一个服务分组/系统配置一个隔离线程池即可,不配置线 程池名称或者相同分组的线程池名称配置为一样。

服务分组+服务+线程池

细粒度实现,一个服务分组中的每一个服务配置一个隔离线程池,为不同的命令实现配置不同的线程池名称即可。

混合实现

一个服务分组配置一个隔离线程池,然后对重要服务单独设置隔离线程池。

(六)Hystrix服务调用的内部逻辑

  1. 构建Hystrix的Command对象, 调用执行方法。
  2. Hystrix检查当前服务的熔断器开关是否开启, 若开启, 则执行降级服务getFallback方法。
  3. 若熔断器开关关闭, 则Hystrix检查当前服务的线程池是否能接收新的请求, 若线程池已满, 则执行降级服务getFallback方法。
  4. 若线程池接受请求, 则Hystrix开始执行服务调用具体逻辑run方法。
  5. 若服务执行失败, 则执行降级服务getFallback方法, 并将执行结果上报Metrics更新服务健康状况。
  6. 若服务执行超时, 则执行降级服务getFallback方法, 并将执行结果上报Metrics更新服务健康状况。
  7. 若服务执行成功, 返回正常结果。
  8. 若服务降级方法getFallback执行成功, 则返回降级结果。
  9. 若服务降级方法getFallback执行失败, 则抛出异常。