Spring Cloud Hystrix 原理

Spring Cloud Hystrix 原理

一、概述

对于熔断这个概念,我们并不陌生,比如股市熔断机制,当股指波幅达到规定的熔断点时,交易所为控制风险采取的暂停交易措施。亦或者是电流熔断,当通过的电流超出导线所能成再的最大电流时,会触发保险丝熔断,从而避免因为电流过大造成火灾。

在这些场景中,可以发现一个共同的特点,就是熔断在这些场景中都是充当保护机制,避免引发更大的问题。那么在整个微服务架构中,也同样会存在类似的问题。

二、服务熔断

在微服务架构中,一个请求过来,可能会经过多个服务进行处理,导致整个处理链路会比较长。而在整条调用链路中,可能会因为某个节点因为网络故障导致响应时间比较长,而这个节点的阻塞将会影响这条链路的结果返回。
当访问量比较高的请求下,一个后端依赖节点的延迟响应可能导致所有服务器上的所有资源在数秒内饱和。一旦出现这个问题,会导致系统资源被快速消耗,从而导致服务宕机等问题,最坏的情况会导致服务雪崩。

为了防止这种问题的产生,也引入了熔断的概念。

所以,熔断的意义:是为了起到保护作用,如果某个目标服务调用比较慢或者大量的超时,这个时候如果触发熔断机制,则可以保证后续的请求不会继续发送到目标服务上,而是直接返回降级的逻辑并且快速释放资源。如果目标服务的情况恢复了,那么熔断机制又会动态进行关闭。

三、服务降级

降级的意思就是:如果主方案行不通,改用备用方案。
比如: 在分布式架构中,A服务调用B服务的时候,由于B服务宕机了,导致请求失败,那这个时候我们有几种方式来处理:

  • 第一种就是返回一个备用的数据,比如“系统繁忙”的信息给到用户,这种就是属于降级;
  • 另一种就是发起重试,这就是容错。

降级实际上有很多的方案主要分两大类,主动降级和被动降级:

  • 主动降级,比如大促的时候关闭非核心服务。
  • 被动降级,熔断触发降级、请求超时触发降级、限流触发降级

四、Hystrix 使用

Hystrix的作用:

  1. 对通过第三方客户端库访问的依赖项(通常是通过网络)的延迟和故障进行保护和控制。
  2. 在复杂的分布式系统中阻止级联故障。
  3. 快速失败,快速恢复。
  4. 回退,尽可能优雅地降级。
  5. 启用近实时监控、警报和操作控制

4.1、熔断触发降级

触发熔断的判断阈值

对某个服务的调用在一定的时间内(默认10s,metrics.rollingStats.timeInMilliseconds),发起了超过一定次数请求(默认20次,circuitBreaker.requestVolumeThreshold),失败率超过一定值(默认50%,circuitBreaker.errorThresholdPercentage),该服务的断路器会打开。返回一个由开发者设定的fallback
熔断的恢复时间(熔断5s),从熔断开启到后续5s之内的请求,都不会发起到远程服务端。

@HystrixCommand(commandProperties = {
@HystrixProperty(name="circuitBreaker.enabled",value ="true"),
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value
= "5"),
@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value =
"5000"),
@HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "50")
},fallbackMethod = "fallback")
@GetMapping("/hystrix/order/{num}")
public String queryOrder(@PathVariable("num")int num){
if(num%2==0){
return "正常访问";
}
//restTemplate默认有一个请求超时时间
return
restTemplate.getForObject("http://localhost:8082/orders",String.class);
}
public String fallback(int num){
//fallback
return "系统繁忙 ";
}

在这里插入图片描述
在这里插入图片描述

4.2、请求超时触发降级

@HystrixCommand(fallbackMethod ="timeoutFallback",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value
= "3000"),
})
@GetMapping("/hystrix/timeout")
public String queryOrderTimeout(){
return
restTemplate.getForObject("http://localhost:8082/orders",String.class);
}

4.3、限流触发降级

信号量隔离

@HystrixCommand(fallbackMethod="semaphoreQuarantineFallback",
commandProperties={
@HystrixProperty(
name=HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY,
value="SEMAPHORE"), // 信号量隔离
@HystrixProperty(
name=HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQU
ESTS,
value="100") // 信号量最大并发数

在这里插入图片描述

线程池隔离

@HystrixCommand(groupKey="order-service",
commandKey = "queryOrder",
threadPoolKey="order-service",
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "30"),//线程池大小
@HystrixProperty(name = "maxQueueSize", value = "100"),//最大
队列长度
@HystrixProperty(name = "keepAliveTimeMinutes", value =
"2"),//线程存活时间
@HystrixProperty(name = "queueSizeRejectionThreshold", value
= "15")//拒绝请求
},
fallbackMethod = "fallback")

在这里插入图片描述

信号量隔离与线程池隔离的区别:

  • 信号量隔离,不会使用Hystrix管理的线程池处理请求。而是使用容器(Tomcat)的线程处理请求逻辑,线程池隔离使用Hystrix管理的线程池。
  • 信号量隔离不涉及线程切换,资源调度,上下文的转换等,相对效率高,线程池隔离涉及这些
  • 信号量隔离不支持异步处理,不支持超时处理,但是可以传递http header,线程池隔离支持异步和超时,但是无法传递http header

五、Hystrix的核心原理

针对类级别的配置(自定义)

  • 可配置化的降级策略:
    • 信号量/线程 、 超时、熔断(错误率)
    • HystrixCommandProperty
  • 可以识别的降级边界:
    • @HystrixCommand(Spring AOP)
    • HystrixCommand 抽象类
  • 数据采集:
    • 如何触发熔断(10s / 20个请求 /错误率)-> 如何采集数据,如何统计数据.
    • SEMAPHORE,最大并发数量 -> AQS ->tryAcquire(), acquire()
  • 行为干预: 触发降级/熔断之后,对正常业务产生影响
  • 结果干预: fallback()
  • 自动恢复(处于熔断状态下,会每隔5s尝试去恢复)

Hystrix的数据统计是采用的滑动窗口(流量控制技术),Hystrix熔断的@HystrixCommand注解,是通过HystrixCommandAspect这个Aop切面来处理的。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值