SpringCloud之Hystrix学习

版权声明:转载请注明出处,谢谢! https://blog.csdn.net/qq_34872748/article/details/84964745

分布式系统面临的问题
扇出
多个微服务互相调用的时候,如果A调用B、C,而B、C又继续调用其他微服务,这就是扇出(像一把扇子一样慢慢打开。
服务雪崩

  • 删除过程中,如果某一个环节的服务出现故障或连接超时,就会导致前面的服务占用越来越多的资源,进而引起系统崩溃,就是“雪崩效应”。
  • 对于高流量的应用来说,单一的后端依赖会导致服务器所有的资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。
    Hystrix介绍
  • 熔断机制的注解是@HystrixCommand
  • 熔断机制是应对雪崩效应的一种链路保护机制,一般存在于服务端
  • 当扇出链路的某个服务出现故障或响应超时,会进行服务降级,进而熔断该节点的服务调用,快速返回“错误”的相应信息。、
  • Hystrix的熔断存在阈值,缺省是5秒内20次调用失败就会触发
    Hystrix源码

熔断案例

  1. 构建一个新的provider module
  2. pom.xml加入hystrix依赖(一定要配合Eureka)
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
  1. application.xml中配置端口和Eureka信息(必配)和其他框架的配置信息(可选,如mybatis)
  2. 编写具体业务逻辑
  3. controller类中,在需要配置Fallback的方法上加入@@HystrixCommand(fallbackMethod = “XXX”)注解,XXX为FallBack方法名本例中作为测试所以抛出了异常
@ResponseBody
    @GetMapping("/dept/{id}")
    @HystrixCommand(fallbackMethod = "nullDeptFallBack")
    public Dept findById(@PathVariable("id")Integer id) {
        Dept dept = deptService.findById(id);
        if (null == dept){
            throw new RuntimeException("返回值为空!");
        }
        return dept;
    }
  1. 根据需要配置FallBack的方法返回值编写代码
 public Dept nullDeptFallBack(@PathVariable("id")Integer id) {
        System.out.println(111);
        return new Dept().setId(id).setDeptName("nullName").setDbSource("nullDB");
    }
  1. 主启动类中加入@EnableCircuitBreaker注解
  2. 开启服务,测试

解耦与降级处理

降级

  • 当系统整体资源快不够的时候,忍痛将部分服务暂时关闭,带渡过难关后,再重新开启。
  • 降级处理时在客户端完成的,与服务端没有关系
  • 理解:所谓降级,一般是从整体负荷考虑,当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的FallBack回调,返回一个缺省值。这样做虽然服务水平下降,但好歹可用,比直接挂掉好。

为什么要解耦

如果按照上面的熔断案例来做的话,Controller下的每个方法,都要给其编写一个FallBack方法,当方法慢慢变多,就会造成代码膨胀,一个是增加编写的工作量,另外一个也会增大维护的难度,代码的耦合度也会高,是十分不合理的,所以要将其解耦。
解耦思路

因为服务端的是通过实现接口访问服务端的,如果在父接口上实现了FallBack方法,通过这样一种方式去维护起来就能实现解耦,也顺便完成了降级的机制。

解耦&降级案例

  1. 在api模块中新建实现了FallbackFactory接口的类,其中泛型T就是我们需要维护其FallBack的接口方法,并实现其create方法,在create方法中返回实现了T的对象,使用匿名内部类实现T。==注意:这个类一定要加@Component注解!!
import com.XXX.entity.Dept;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class DeptClientServiceFallBackFactory implements FallbackFactory<DeptClientService> {
    public DeptClientService create(Throwable throwable) {
        return new DeptClientService() {
            public boolean addDept(Dept dept) {
                return false;
            }

            public List<Dept> findAll() {
                return null;
            }

            public Dept findById(Integer id) {
                return new Dept().setId(id).setDeptName("服务器跪了,").setDbSource("迟点来吧");
            }
        };
    }
}
  1. 修改步骤1中传入的泛型T接口,添加@FeignClient(fallbackFactory = T.class)注解
@FeignClient(value = "MICROSERVICECLOUD-DEPT",fallbackFactory = DeptClientServiceFallBackFactory.class)
public interface DeptClientService {

    @PostMapping("/dept")
    public boolean addDept(Dept dept);

    @GetMapping("/dept")
    public List<Dept> findAll();

    @GetMapping("/dept/{id}")
    public Dept findById(@PathVariable("id")Integer id);
}
  1. 修改consumer feign模块的application.xml文件,开启hystrix(注:在IDEA中可能没有代码提示,开启的true也没有正常高亮,但好像不需要做额外操作也不影响结果)
feign:
  hystrix:
    enabled: true
  1. 开启服务并测试

猜你喜欢

转载自blog.csdn.net/qq_34872748/article/details/84964745
今日推荐