• SpringCloud 09 Hystrix 服务熔断


    9.1 什么是 Hystrix


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

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

    Hystrix 能干嘛

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

    9.2 什么是 服务熔断

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

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


    9.3 尝试 服务熔断机制

    1. 新建一个 springcloud-provider-dept-hystrix-8001 来测试 hystrix 的 服务熔断。

    在这里插入图片描述
    2. 导入 Hystrix 依赖

            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starter-netflix-hystrixartifactId>
                <version>2.2.10.RELEASEversion>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    3. 我们正常来说,如果 服务请求/方法 出现了异常,肯定要 抛出 这个异常!比如说这样做!id 如果 传递 过来的是 一个压根就找不到的 id,那么 肯定 不对劲,所以要抛出异常。

    package top.muquanyu.springcloud.controller;
    
    
    import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.cloud.client.discovery.DiscoveryClient;
    import org.springframework.web.bind.annotation.*;
    import top.muquanyu.springcloud.pojo.Dept;
    import top.muquanyu.springcloud.service.DeptServiceImpl;
    
    import java.util.List;
    
    // 提供 RestFul 服务的 就只能是 Controller 接口
    @RestController
    public class DeptController {
    
        @Autowired
        private DeptServiceImpl deptService;
    
    
        @GetMapping("/dept/get/{id}")
        public Dept get(@PathVariable("id") Long id){
            // 这个方法 其实 是有问题的,如果 id 传过来的 是找不到的呢。。是没有的呢?
            // 那么 我们 是不是 就查不到了?
            Dept dept = deptService.queryByID(id);
            if(dept == null){
                throw new RuntimeException("id => "+ id + " 不存在该 Dept 对象");
            }
            return dept;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    在这里插入图片描述

    1. 使用 @EnableHystrix@@HystrixCommand 注解 体验 Hystrix 服务熔断
    package top.muquanyu.springcloud.controller;
    
    
    import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.cloud.client.discovery.DiscoveryClient;
    import org.springframework.web.bind.annotation.*;
    import top.muquanyu.springcloud.pojo.Dept;
    import top.muquanyu.springcloud.service.DeptServiceImpl;
    
    import java.util.List;
    
    // 提供 RestFul 服务的 就只能是 Controller 接口
    @RestController
    public class DeptController {
    
        @Autowired
        private DeptServiceImpl deptService;
    
    
        @GetMapping("/dept/get/{id}")
        @HystrixCommand(fallbackMethod = "hystrixGet")
        public Dept get(@PathVariable("id") Long id){
            // 这个方法 其实 是有问题的,如果 id 传过来的 是空的呢。。
            // 那么 我们 是不是 就查不到了?
            Dept dept = deptService.queryByID(id);
            if(dept == null){
                throw new RuntimeException("id => "+ id + " 不存在该 Dept 对象");
            }
            return dept;
        }
    
        // 备选方案
        public Dept hystrixGet(@PathVariable("id") Long id){
            return new Dept().setDeptno(id).setDname("id => "+ id + " 没有对应的信息,null --@Hystrix").setDb_source("no this database in MySQL");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    在这里插入图片描述
    在这里插入图片描述
    服务熔断 效果,实现 成功!

    一个 可以显示 服务提供者 IP 地址的 配置:eureka.instance.perfer-ip-address: true

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

  • 相关阅读:
    通用后台管理系统前端界面Ⅺ——信息列表页(弹窗复用增改、CRUD前端基础实现)
    〖大前端 - 基础入门三大核心之JS篇㊲〗- DOM改变元素节点的css样式、HTML属性
    数据结构与算法复习:第三十二弹
    Renesas:如何指定段(地址)存放数据
    ssm和springboot整合
    数据中台详解
    一个发誓不用Java的程序员,不得不在太空中调试Lisp
    【LeetCode】剑指 Offer Ⅱ 第7章:队列(6道题) -- Java Version
    Oracle将归档日志从 ASM 拷贝到 Linux 文件系统中操作步骤
    【LeetCode】1838. 最高频元素的频数
  • 原文地址:https://blog.csdn.net/qq_52606908/article/details/126242329