SpringCloud(七):Hystrix断路器(二)

目录

服务熔断

熔断机制概述

服务熔断实操

修改cloud-provider-hystrix-payment8001

PaymentService

PaymentController

 测试

熔断类型

    熔断打开

    熔断关闭

    熔断半开

断路器在什么情况下开始起作用

 Hystirx工作流程

服务限流


服务熔断

熔断机制概述

熔断是什么?

这个概念由martin fowler 提出->Martin Fowler 博客里关于断路器的介绍

熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点的服务的调用,快速返回错误响应信息。

当检测到该节点微服务响应正常以后,恢复调用链路。(相较于服务降级返回的备用策略,服务熔断不一样的是等状况好转以后会试着恢复调用链路,回到正轨调用方案上

在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用状况,当失败的调用到一定的阈值,缺省是5秒内20次调用失败,就会启动熔断机制。

熔断机制的注解是@HystrixCommand

 

简单来讲,断路器有三种状态,关闭,打开,半打开。

正常的调用情况下,断路器是关闭的,当某种情况出现,比如高并发的情况下,导致系统瘫痪,断路器将打开,此时将不能进行正常调用了。此时访问量就逐渐减少,当有少量访问的时候,断路器半打开状态,断路器会试着恢复链路,少量的请求范围系统,如果能够正常运行,则恢复正常链路。

 电路开关闭的确切方式:(这段话来自hystirx的GitHub 的wiki板块,How-it-Works

  • 假设请求次数到达一定的阈值
  • 假设错误率错过阈值的错误率
  • 然后断路器从CLOSED过渡到OPEN
  • 当断路器是打开状态,会对所有的请求进行短路
  • 在一段时间之后(HystrixCommandProperties.circuitBreakerSleepWindowInMilliseconds()),下一个请求被允许通过(这是HALF-OPEN状态)。如果请求失败,断路器在休眠窗口期间返回OPEN状态。如果请求成功,断路器转换为CLOSED

服务熔断实操

修改cloud-provider-hystrix-payment8001

PaymentService

忽略头上的一系列注解,这本身是一个简单的方法,输入数字,若为负数,则报错,然后被服务降级到paymentCircuitBreaker_fallback方法里面。

    //服务熔断
    @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback", commandProperties = {
            //是否开启断路器
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
            //请求次数
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
            //时间范围
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
            //失败率达到多少后跳闸
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),
    })
    public String paymentCircuitBreaker(@PathVariable("id") Integer id) {
        if (id < 0) {
            throw new RuntimeException("*****id 不能负数");
        }
        String serialNumber = IdUtil.simpleUUID();

        return Thread.currentThread().getName() + "\t" + "调用成功,流水号:" + serialNumber;
    }

    public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id) {
        return "id 不能负数,请稍候再试,(┬_┬)/~~     id: " + id;
    }

根据断路器打开的要求

我们根据circuitBreaker.enabled启用了断路器

@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),

通过circuitBreaker.requestVolumeThreshold规定了请求次数

@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),

通过sleepWindowInMilliseconds规定了时间窗口期,比如在10秒的窗口期,我们10次访问,失败率达到60%,就开启断路器。

@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),

通过circuitBreaker.errorThresholdPercentage规定了失败率超过多少后开启断路器

@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),

接下来再分析分析@HystrixProperty属性里的要求,这些属性来自哪里?

HystrixCommandProperties 这个类规定了HystrixCommand注解下的HystrixProperty属性里的值。 

PaymentController

    /**
     * 服务熔断
     *
     * @param id 主键
     * @return 
     */
    @GetMapping("/payment/circuit/{id}")
    public String paymentCircuitBreaker(@PathVariable("id") Integer id) {
        String result = paymentService.paymentCircuitBreaker(id);
        log.info("*******result:" + result);
        return result;
    }

 测试

输入正数正常访问成功

输入负数进入了服务降级的方法中

 

 输入多次放一首歌有,开启了短路模式,此时用正数访问也不能成功了

然后再不断输入正数,达到一定的成功率,恢复链路,能够正常访问了

熔断类型

    熔断打开

请求不再进行调用当前服务,内部设置时钟一般为MTTR(平均故障处理时间),当打开时长达到所设时钟则进入熔断状态

    熔断关闭

熔断关闭不会对服务进行熔断

    熔断半开

部分请求根据规则调用当前服务,如果请求成功且符合规则则认为当前服务恢复正常,关闭熔断 

断路器在什么情况下开始起作用

  • 当满足一定阀值的时候(默认10秒内超过20个请求次数)
  • 当失败率达到一定的时候(默认10秒内超过50%请求失败)
  • 到达以上阀值,断路器将会开启
  • 当开启的时候,所有请求都不会进行转发
  • 一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4和5

涉及到断路器的三个重要参数:快照时间窗口请求总数阈值错误百分比阈值

快照时间窗口

断路器确定是否需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗口,默认为最近的10秒

请求总数阈值

在快照时间窗内,必须满足请求总数的阈值才有资格熔断,默认是20,意味着在10秒内,如果该hystirx命令的调用次数不足20次,即使所有的请求都超时或者其他原因失败,断路器都不会打开。

错误百分比阈值

当请求总数在快照时间窗内超过了阈值,比如发生了30次调用,如果在这30次调用中,有15次发生了50%的错误百分比,在默认设定50%阈值情况下,这时候断路器打开。

 Hystirx工作流程

参考:SpringCloud-Hystrix原理

下图来自Hystrix官网,其描述了Hystrix的工作流程

 转换成流程图,如下所示:

 

以下部分将更详细地解释此流程:

  1. 构造一个HystrixCommandHystrixObservableCommand对象

  2. 执行命令

  3. 是否启用了缓存并且命中缓存?
  4. 断路器是否开启》?
  5. 是否有可用资源?(比如线程,队列)
  6. 执行远程调用HystrixCommand.run()或者HystrixObservableCommand.construct()
  7. 报告服务健康情况
  8. 服务降级
  9. 返回结果

服务限流

鉴于Hystrix已停止更新,后面会讲解alibaba的Sentinel,但Hystrix的整个理念都非常的好,值得学习。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值