• 【分布式】SpringCloud(6)--Hystrix服务熔断与降级


    1.Hystrix概述

    1.1.什么是Hystrix

    Hystrix是一个用于处理分布式系统的延迟和容错的开源库。Hystrix主要用于处理分布式系统中复杂多变的服务依赖调用失败、超时、异常等情况,保证一个服务依赖出问题的情况下,提供一个服务预期的、可处理的备选响应(FallBack),避免微服务整体级联故障,以提高分布式系统的弹性。

    1.2.Hystrix的作用是什么

    Hystrix旨在执行以下操作:

    • 提供保护并控制延迟和失败,以及通过第三方客户端库(通常是通过网络)访问依赖项导致的失败。
    • 切断复杂的分布式系统中的级联故障。
    • 快速响应并快速恢复。
    • 回退并在可能的情况下正常降级。
    • 启用近乎实时的监视,警报和操控。

    1.3.Hystrix能解决什么问题

    Hystrix在分布式项目中主要用于处理:

    • 服务降级
    • 服务熔断
    • 服务限流
    • 接近实时地监控

    2.Hystrix服务熔断

    2.1.服务熔断机制

    首先对应服务熔断我们要理解“服务雪崩”的概念,服务雪崩是多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,就是所谓的“雪崩”。

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

    当扇出链路的某个微服务不可用或者响应时间太长时,就会通过熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。

    2.2.简单实现一个Hystrix熔断

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

    这里我们还是基于我们之前博客的微服务项目springcloud-provider-dept-8001 服务端 复制一份作为hystrix的微服务项目。

    ①添加hystrix pom.xml依赖包:

    <!--引入hystrix-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>

    ②修改application.yml配置,修改了实例名称:

    server:
      port: 8001
    ##省略了数据库连接信息与mybatis配置
    
    #eureka的配置,确定客户端服务注册到eureka服务列表内
    eureka:
      client:
        service-url:
          #集群配置
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
          #defaultZone: http://localhost:7001/eureka/
      instance:
        instance-id: springcloud-provider-dept-hystrix-8001  #修改eureka上默认的服务描述信息
        prefer-ip-address: true  #访问路径可以显示ip地址

    ③基于Controller层的调用方法通过id获取Dept用户来做异常判定:

    @RestController
    @RequestMapping("/dept")
    public class DeptController {
        @Autowired
        private DeptService service;
    
        @GetMapping("/queryById/{id}")
        /*@HystrixCommand表示一旦调用服务方法失败并抛出了异常信息之后,
        会自动调用@HystrixCommand标注好的fallbackMethod中指定名称的方法*/
        @HystrixCommand(fallbackMethod = "processHystrixGet")
        public Dept queryById(@PathVariable("id") Long id){
            Dept dept = service.queryById(id);  //模拟当查询不到id或者id信息异常时返回错误异常的提示
            if(null == dept){
                throw new RuntimeException("id=>" + id + "不存在该用户,或者用户信息无法找到!");
            }
            return dept;
        };
    
        //熔断备选方法:异常回调信息显示
        public Dept processHystrixGet(@PathVariable("id") Long id){
            return new Dept()
                    .setDeptno(id)
                    .setDname("id=>" + id + "没有对应的信息,null--@Hystrix")
                    .setDbSource("no this database in MySQL");
        }
    }

    ④在主启动类上添加对hystrix的熔断机制的支持:

    @SpringBootApplication
    @EnableEurekaClient  //在服务启动后自动注册到eureka中
    @EnableDiscoveryClient  //服务发现
    @EnableCircuitBreaker  //启用对hystrix的熔断机制的支持
    public class DeptProvider8001_Hystrix_App {
        public static void main(String[] args) {
            SpringApplication.run(DeptProvider8001_Hystrix_App.class, args);
        }
    }

    ⑤启动Eureka客户端、Hystrix服务端进行访问验证:

    访问正常存在的服务id,能返回正常数据:

    访问异常不存在的id时,返回fallback方法中的信息:

     可以看出,当执行调用某个微服务发生异常时,Hystrix能通过自定义的fallbackMethod做异常的错误返回,快速进行异常熔断机制。

    服务熔断是在服务运行的情况下,对于服务内部执行错误的异常情况的一种处理方式。

    3.Hystrix服务降级

    3.1.服务降级机制

    服务降级是从网站整体的负载考虑,当某个服务在某一时间内承受大量的服务请求,而需要极大的资源消耗,需要关闭当前系统的某些服务,做资源的扩充。牺牲单个服务的运行,当再次访问这单个服务的时候,通过服务降级处理,返回给客户设定的默认缺省值

    相当于弃军保帅,维护的是整个系统的可用性。

    3.2.简单实现服务降级

    服务降级这里从客户端进行实现。

    (1)首先在springcloud-api中定义一个降级之后的回调函数类,实现FalllbackFactory接口,接口中实现了对应请求信息的异常处理方法:

    @Component  //注意不要忘记添加,需要把类加载进Spring容器中才能获取到
    public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService> {
        @Override
        public DeptClientService create(Throwable throwable) {
            return new DeptClientService() {
                @Override
                public boolean addDept(Dept dept) {
                    return false;
                }
    
                @Override
                public Dept queryById(Long id) {
                    return new Dept().setDeptno(id).setDname("该ID:" + id + "没有对应的信息,Consumer客户端提供的降级信息,此刻服务provider已经关闭").
                            setDbSource("no this database in MySQL");
                }
    
                @Override
                public List<Dept> queryAll() {
                    return null;
                }
            };
        }
    }

    (2)对应api接口中使用fallabckFatory去指定调用的是哪个class实现类:

    //value中对应服务提供方的名字
    //服务降级:表示DeptClientService当前接口中任何一个方法出了问题:都去找DeptClientServiceFallbackFactory回调处理
    @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT", fallbackFactory = DeptClientServiceFallbackFactory.class)
    @Component //注入到容器中
    public interface DeptClientService {
        /**
         * 接口中的三个方法对应服务提供者的三个方法
         * 这里面的接口对应服务提供者的controller接口,名称必须一致,然后接口的Mapping映射url必须一致
         * @param dept
         * @return
         */
    
        @PostMapping("/dept/add")
        public boolean addDept(Dept dept);
    
        @GetMapping("/dept/queryById/{id}")
        public Dept queryById(@PathVariable("id") Long id);
    
        @GetMapping("/dept/queryAll")
        public List<Dept> queryAll();
    }

    (3)基于FeignClinet调用,则需要修改服务提供者中application.yml,开启feign中对hystrix的支持:

    #开启降级feign.hystrix支持
    feign:
      hystrix:
        enabled: true

    (4)测试验证:

    步骤:启动三个Eureka注册中心7001、7002、7003,启动provider-dept-8001作为服务提供者、启动consumer-dept-feign服务消费者:

    可以看到服务提供者已经注册进去并正常运行:

    通过客户端consumer-feign的81端口也能访问到对应的id数据:

    (5)模拟服务熔断异常:

    关闭服务提供方provider-dept-8001,同时访问81端口的数据请求:

     可以看到此时调用到了我们编写的fallbackFactory中的回调方法显示降级信息。

    所以即使服务关闭之后,Hystrix的服务熔断机制也能避免大量重复无效访问带来的服务异常,能较好的提供客户体验。

    本节涉及实例及相关代码已上传至github:

    https://github.com/devyf/SpringCloud_Study/tree/main/springcloud_hello

  • 相关阅读:
    [kafka] 005_kafka_Java_API
    [kafka] 004_kafka_安装运行
    [kafka] 003_kafka_主要配置
    [kafka] 002_kafka_相关术语详细解析
    [kafka] 001_kafka起步
    [随想感悟] 《归去来兮辞·并序》 赏析
    [hadoop] 一些基础概念
    [kylin] 部署kylin服务
    CSAPP 读书笔记
    ubuntu下安装vmTools, 和共享文件
  • 原文地址:https://www.cnblogs.com/yif0118/p/14616744.html
Copyright © 2020-2023  润新知