服务降级之Hystrix豪猪(下)

一、Hystrix之全局服务降级DefaultProperties(DefaultFallback)

1、为什么要有全局服务降级?

有上一篇我们可知,我们在业务类OrderController中为需要降级的服务配置了一个服务降级处理方法,但是当业务方法很多的时候,为每个方法单独配置一个降级方法,显然很傻X,代码必然要膨胀!

没有配置过的就找全局通用的Defalut,单独配置的就使用自己专门配置的降级方法;

DefaultProperties(DefaultFallback = “ ”)

1:1每个方法配置一个降级方法,技术上可行,实际上是傻X;

1:N除了个别重要的核心业务有专属,其他的普通的可以通过DefaultProperties(DefaultFallback = “ ”)统一跳转到统一处理页面

通用和独享的各自分开,避免了代码膨胀,合理减少了代码量!

2、修改OrderController:

@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
public class OrderHystrixController {
    @Autowired
    private PaymentHystrixService paymentHystrixService;

    @GetMapping(value = "/consumer/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id){
        return paymentHystrixService.paymentInfo_OK(id);
    }

    @GetMapping(value = "/consumer/payment/hystrix/timeout/{id}")
    @HystrixCommand
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
        return paymentHystrixService.paymentInfo_TimeOut(id);
    }

    public String paymentInfo_TimeOutHandler(Integer id){
        return "我是消费者Order80,对方Payment8001系统繁忙,请10秒钟后再试 o(╥﹏╥)o";
    }

    public String payment_Global_FallbackMethod(){
        return "Global降级处理信息,请稍后再试 o(╥﹏╥)o";
    }
}

3、启动测试:

75.jpg

可见全局服务降级 DefaultProperties(DefaultFallback) 奏效;


二、Hystrix之通配服务降级FeignFallback

1、在现有PaymentHystrixService接口的基础上,新建一个类PaymentFallbackService实现上面的接口:

@Service
public class PaymentFallbackService implements PaymentHystrixService {
    @Override
    public String paymentInfo_OK(Integer id) {
        return "------PaymentFallbackService-paymentInfo_OK  o(╥﹏╥)o---";
    }

    @Override
    public String paymentInfo_TimeOut(Integer id) {
        //如果失败就会进入方法体,实现服务降级
        return "------PaymentFallbackService-paymentInfo_TimeOut  o(╥﹏╥)o---";
    }
}

2、在@FeignClient接口上配置服务降级的实现类:

@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT", fallback = PaymentFallbackService.class)

3、启动测试:

先正常访问:

76.jpg

在将Payment8001停止,模拟宕机:

77.jpg

显然FeignFallback实现了在@Feign接口上的服务降级!


三、服务熔断Break

服务熔断比服务降级严重——服务熔断必定触发服务降级——可视为更严重的服务降级

1、熔断机制概述:

熔断机制是应对雪崩效应的一种微服务链路保护机制。

当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息!

检测到该节点微服务调用响应正常后恢复调用链路

在spring cloud框架里,熔断机制是通过Hystrix实现的,Hystrix会监控微服务间调用的状况;

当失败的调用到一定的阈值后,缺省是5秒内20次调用失败,机会启动熔断机制,熔断机制的注解还是 @HystrixCommand 

2、熔断器原理图:

78.jpg


四、服务熔断实战

1、在服务提供者Payment8001的处理类PaymentService中增加一个服务熔断方法paymentCircuitBreaker:

@Service
public class PaymentService {
    //服务熔断
    @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")  //失败率达到多少后跳闸
    })
    //**上面的翻译:在10秒钟的时间窗口期中,有10次请求,其他60%即6次是失败的,则断路器跳闸**
    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不能为负数,请稍后再试 o(╥﹏╥)o id为:" + id;
    }
}

commandProperties 中的大量配置,如何获知?——HystrixCommandProperties类

其中还记载着对应的默认值:

80.jpg

官网:

79.jpg

2、在PaymentController中增加一个调用方法:

@RestController
@Slf4j
public class PaymentController {
    @Autowired
    private PaymentService paymentService;
    
    //服务熔断
    @GetMapping("/payment/circuit/{id}")
    public String paymentCircuitBreaker(@PathVariable("id") Integer id){
        String result = paymentService.paymentCircuitBreaker(id);
        log.info("****result:" + result);
        return result;
    }
}

3、启动Payment8001服务,进行测试:

 http://localhost:8001/payment/circuit/1 id为正数时,一切正常,调用成功!

81.jpg   

http://localhost:8001/payment/circuit/-1  id为负数时,爆出异常后,进入服务降级方法

82.jpg

但是注意,此时只是正常的服务降级而已!还没触发断路器!!!

4、现在我们要人工触发断路器跳闸,注意:

id为-1时为失败,我们不停地点击,然后断路器跳闸后,迅速地访问id为1的情况,此时即使id为1,也无法访问,因为链路已经跳闸断开了!

83.jpg

过了一会儿,当断路器恢复Closed后,id为1时,又可以访问了:

84.jpg

即,Hystrix断路器 检测到该节点微服务调用响应正常后恢复调用链路

5、Hystrix熔断器总结:

熔断类型:

  • 熔断关闭Closed:闭合状态,链路调用正常

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

  • 熔断半开Half Open:部分请求根据规则调用当前服务,如果请求成功且符合规则则认为当前服务恢复正常,熔断器闭合,链路调用恢复正常

6、一张官网的熔断器详细流程图镇楼:

85.jpg

熔断器涉及到的三个重要参数:

快照时间窗口(默认为最近的10秒)、请求总数阈值(默认为20次)、错误百分比阈值(默认为50%)

即默认断路器跳闸条件是: 在最近的10秒类,有20次请求,且其中50%,即10次以上失败,才会熔断!

86.jpg

7、熔断器跳闸后发生的事?

再有请求调用的时候,将不会调用主逻辑,而是直接调用降级fallback方法,通过断路器,实现了自动地发现错误将降级逻辑切换为主逻辑,减少响应延时的效果!

8、原来的主逻辑要如何恢复?

对于这一问题,Hystrix也为我们实现了自动恢复功能:

当断路器打开,对主逻辑进行熔断之后,hystrix会启动一个休眠时间窗口,在这个时间窗口内,降级逻辑临时地成为了主逻辑

休眠时间窗口到期后,断路器将进入半开状态释放一次请求到原来的主逻辑上,如果此次请求正常返回,那么断路器将闭合,主逻辑恢复

如果这次请求依然有问题,断路器继续进入断开状态,休眠时间窗口重新开始计时!!!


七、Hystrix图形化Dashboard的搭建

1、除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求执行信息,并以统计报表和图形化的形式展示给用户,包括每秒执行多少请求,多少成功,多少失败等。

Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,将监控内容转化成可视化界面。

2、Hystrix Dashboard监控项目搭建——项目cloud-consumer-hystrix-dashboard9001

pom.xml中核心依赖:

<dependencies>
    <!--Hystrix Dashboard-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <!--热部署devtools-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>

    <!--lombok-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <!--测试-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
</dependencies>

3、application.yml配置文件:

server:
  port: 9001

4、主启动类:HystirxDashboardMain9001.java:

@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardMain9001 {
    public static void main(String[] args) {
        SpringApplication.run(HystrixDashboardMain9001.class, args);
    }
}

5、启动项目,访问: localhost:9001/hystrix ,当看到如下界面,说明我们的Dashboard服务已经搭建完成;

87.jpg


八、Hystrix图形化Dashboard的使用

1、如果某个项目需要被Hystrix Dashboard除了要引入actuator依赖外,还必须要做另一件事:

需要在主启动类中增加以下Bean注入,这是Springcloud升级后的坑:

以项目HystrixPayment8001为例:

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class PaymentHystrixMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentHystrixMain8001.class, args);
    }

    /**
     * 此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑;
     * ServletRegistrationBean 是因为springboot的默认路径不是“/hystrix.stream”;
     * 只要在自己的项目里配置上此配置Bean注入即可;
     * @return
     */
    @Bean
    public ServletRegistrationBean getServlet(){
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

2、之后启动项目,以下面的方式配置所要监控的 payment8001项目:

88.jpg

3、在点击Monitor Stream为了看到监控效果,我们先多访问几次以下路径,分别对这种正常访问和不正常访问:

http://localhost:8001/payment/circuit/1

http://localhost:8001/payment/circuit/1

90.jpg

以上图中的几处:

  • 7色:不同的颜色对应着不同的请求状态,上图有明确解释

  • 1圈——实心圈:两层含义:

    • 颜色:代表实例的健康程度: 绿色 > 黄色 > 橙色 > 红色 

    • 大小:大小会根据实例的请求流量发生变化,流量越大,实心圆越大;

    所以,通过该实心圆的展示就可以在大量的实例中快速地发现 故障实例和高压力实例!

  • 1线:用来记录2分钟内的流量的相对变化,可以通过它来观察到流量的上升和下降趋势;

4、整图详细说明:

91.jpg

92.jpg

5、更详细的图解:

93.jpg

6、最终,我们实际生产中,服务监控模板可能就是这个样子:

94.jpg

到了这里,Hystrix的内容就差不多结束了,关于服务限流,在学习 Sentinel 的时候一并学习;

Hystrix Dashboard有一点不好就是还需要我们自己去搭建服务监控平台,等到时候Sentinel的时候,就不需要自己搭建了,Sentinel提供了自己的服务监控界面,直接网址访问!

个人此项目代码地址(持续更新):

https://github.com/jiguiquan/cloud2020

jiguiquan@163.com

文章作者信息...

留下你的评论

*评论支持代码高亮<pre class="prettyprint linenums">代码</pre>

相关推荐