zoukankan      html  css  js  c++  java
  • SpringCloud(7)

    一、前言

    1)分布式系统面临的问题

    复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败!

    当一切正常时,请求看起来是这样的:

    当其中有一个系统有延迟时,它可能阻塞整个用户请求:

    2)服务雪崩

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

    对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。

    3)什么是Hystrix

    Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

    “断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

    4)Hystrix能干什么

    ① 服务降级
    ② 服务熔断
    ③ 服务限流
    ④ 接近实时的监控
    ⑤ …

    二、服务熔断

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

    当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回”错误”的响应信息。当检测到该节点微服务响应正常后恢复调用链路,在 SpringCloud 框架机制通过Hystrix实现,Hystrix 会监控微服务见调用的状况,当失败的调用到一个阈值,缺省是5秒内20次调用失败就会启动熔断机制,熔断机制的注解是 @HystrixCommand 

    1)代码实现

    新建一个服务提供者模块 spirngcloud-provider-dept-hystrix-8001 

    内容保持和 spirngcloud-provider-dept-8001 相同,修改主启动类的类名和 yaml 中的 instance-id

    ① 导入 Hystrix 的依赖

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

    ② 把之前的 Controller 中的代码删掉,重新编写

    @RestController
    public class DeptController {
    
        @Autowired
        public DeptService deptService;
    
        @RequestMapping("/dept/get/{id}")
        @HystrixCommand(fallbackMethod = "hystrixGet") // 使用HystrixCommand注解,在fallbackMethod属性中指定fallback的方法
        public Dept get(@PathVariable("id") Long id) {
            Dept dept = deptService.queryById(id);
            if (dept == null) {
                throw new RuntimeException("id => " + id + ",不存在该用户或者信息找不到!!!");
            }
            return dept;
        }
    
        // 备选方案:覆写fallbackMethod中指定的方法,注意,此方法的返回值,参数必须与原方法一致
        public Dept hystrixGet(@PathVariable("id") Long id) {
            return new Dept()
                    .setDeptno(id)
                    .setDname("id => " + id + ",不存在该用户或者信息找不到!!!")
                    .setDb_source("no database in MySQL!!!");
        }
    
    }

    ③ 在主启动类添加对熔断的支持 @EnableCircuitBreaker 

    // 启动类
    @SpringBootApplication
    @EnableEurekaClient     // 在服务启动后自动注册到Eureka中
    @EnableDiscoveryClient  // 服务发现
    @EnableCircuitBreaker   // 添加对熔断的支持
    public class DeptProviderHystrix_8001 {
        public static void main(String[] args) {
            SpringApplication.run(DeptProviderHystrix_8001.class, args);
        }
    }

    ④ 启动测试

    这样,在访问 localhost/consumer/queryById/123456789 时,因为此id不存在,所以会出现异常,这样就调用了我们备用的方法

    三、服务降级

    服务降级,当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。比如电商平台,在针对618、双11等高峰情形下采用部分服务不出现或者延时出现的情形。

    1)代码实现

    springcloud-api 模块中,新建一个类 DeptClientServiceFallbackFactory ,实现 FallbackFactory 接口,并添加注解 @Component ,将该类放入 IOC 中,实现其中的方法

    // 服务降级
    @Component
    public class DeptClientServiceFallBackFactory implements FallbackFactory {
        @Override
        public DeptClientService create(Throwable throwable) {
            return new DeptClientService() {
                @Override
                public Dept queryById(Long id) {
                    return new Dept()
                            .setDeptno(id)
                            .setDname("id==>" + id + ",没有对应的信息,客户端提供了降级的信息,这个服务现在已经被关闭")
                            .setDb_source("没有数据");
                }
    
                @Override
                public List<Dept> queryAll() {
                    return null;
                }
    
                @Override
                public boolean addDept(Dept dept) {
                    return false;
                }
            };
        }
    }

    DeptClientService 接口上,添加注解 @FeignClient(fallbackFactory = DeptClientServiceFallbackFactory.class) 

    @Component
    @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT", fallbackFactory = DeptClientServiceFallBackFactory.class)
    public interface DeptClientService {
    
        @GetMapping("/dept/get/{id}")
        public Dept queryById(@PathVariable("id") Long id);
    
        @GetMapping("/dept/list")
        public List<Dept> queryAll();
    
        @GetMapping("/dept/add")
        public boolean addDept(Dept dept);
    }

    springcloud-consumer-dept-feign 模块的 yaml 中配置,开启降级服务

    # 开启服务降级
    feign:
      hystrix:
        enabled: true

    测试

    在访问该服务时,关闭该服务后,会出现提示

    2)服务熔断与服务降级对比

    服务熔断:在服务端处理,某个服务超时或异常,引起熔断

    服务降级:在客户端处理,从整个网站的负载考虑,当某个服务熔断或者关闭之后,服务将不再被调用,此时在客户端,我们可以准备一个自己的失败回调Fallback,返回一个默认值(缺省值),整体的服务水平下降了,但是好歹能用,总比直接挂掉要好

    四、Dashboard流量监控

    新建一个模块 springcloud-consumer-hystrix-dashboard ,导入依赖

    <!-- hystrix依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!-- hystrix-dashboard监控 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!-- Ribbon负载均衡 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-ribbon</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!-- Eureka服务提供 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--实体类-->
    <dependency>
        <groupId>com.cyan</groupId>
        <artifactId>springcloud-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <!--web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--热部署工具-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>

    application.yaml 配置端口号

    server:
      port: 9001

    创建一个启动类,并添加注解 @EnableHystrixDashboard ,开启监控

    @SpringBootApplication
    @EnableHystrixDashboard // 开启监控
    public class DeptComsumerDashBoard_9001 {
        public static void main(String[] args) {
            SpringApplication.run(DeptComsumerDashBoard_9001.class, args);
        }
    }

    要保证我们的服务者模块都要有 spring-boot-starter-actuator 依赖和 hystrix 依赖,来完成监控

    <!-- hystrix依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!-- actuator完善eureka监控信息 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    只启动该监控服务,访问 localhost:9001/hystrix 

    如果想要一个服务被监控,我们需要加一个Bean

    spirngcloud-provider-dept-8001 模块,主启动类中,添加

    @SpringBootApplication
    @EnableEurekaClient     // 在服务启动后自动注册到Eureka中
    @EnableDiscoveryClient  // 服务发现
    public class DeptProvider_8001 {
        public static void main(String[] args) {
            SpringApplication.run(DeptProvider_8001.class, args);
        }
    
        @Bean
        public ServletRegistrationBean hystrixMetricsStreamServlet() {
            ServletRegistrationBean<Servlet> registrationBean = new ServletRegistrationBean<>(new HystrixMetricsStreamServlet());
            registrationBean.addUrlMappings("/actuator/hystrix.stream");
            return registrationBean;
        }
    }

    测试

    启动注册中心,启动流量监控,启动该 8001 服务

    访问 localhost:9001/hystrix ,将 localhost:8001/actuator/hystrix.stream ,添加到监控

    会自动跳转到监控页面

  • 相关阅读:
    0317复利计算的回顾与总结
    0518 Scrum 项目 5.0
    0517 Scrum 项目4.0
    0512 Scrum 项目3.0
    实验三 进程调度模拟程序
    0505 Scrum 项目1.0
    0502团队项目 SCRUM团队成立
    0428 团队项目2.0
    0422团队项目
    实验二 作业调度模拟程序
  • 原文地址:https://www.cnblogs.com/Dm920/p/13195542.html
Copyright © 2011-2022 走看看