Hystrix 断路器

分布式系统面临的问题
复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。
服务雪崩
多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的“雪崩效应”.
对于高流量的应用来说,单一的后避依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。
所以,通常当你发现一个模块下的某个实例失败后,这时候这个模块依然还会接收流量,然后这个有问题的模块还调用了其他的模块,这样就会发生级联故障,或者叫雪崩。
hystrix是什么:
在分布式环境中,许多服务依赖项中的一些必然会失败。Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、停止级联失败和提供回退选项来实现这一点,所有这些都可以提高系统的整体弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
服务降级
服务器忙,请稍后再试,不让客户端等待并立刻返回一个友好提示,fallback
哪些情况会出发降级

  • 程序运行导常
  • 超时
  • 服务熔断触发服务降级
  • 线程池/信号量打满也会导致服务降级

服务熔断
类比保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示。
服务的降级 -> 进而熔断 -> 恢复调用链路
服务限流:
秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行。
demo:

  • 1.添加依赖 ```
    1. <!--hystrix-->
    2. <dependency>
    3. <groupId>org.springframework.cloud</groupId>
    4. <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    5. </dependency>
  1. - 2.[EnableCircuitBreaker ](/EnableCircuitBreaker ) 启动类添加注解使用hystrix断路器功能

@MapperScan(“com.zds.egg.*.mapper”) @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients @EnableCaching @EnableScheduling @EnableCircuitBreaker // hystrix public class HystrixMain {

  1. public static void main(String[] args) {
  2. SpringApplication.run(HystrixMain.class, args);
  3. }

}

  1. - 3.mapper 通过fegin调用另一个服务

//@FeignClient(name=”zds-egg-biz”, fallback = RemoteHystrix.class) // feign @FeignClient(name=”zds-egg-biz”) // hystrix @Component public interface BizClient {

  1. @GetMapping("selectStus")
  2. List<StudentEntity> selectStus();
  3. // hystrix
  4. @GetMapping("timeout/{time}")
  5. List<StudentEntity> timeout(@PathVariable("time") Integer time);

}

  1. - 4.service

public interface StudentService extends IService { // hystrix String istimeout(Integer time) throws InterruptedException; }

  1. - 5.serviceImpl @HystrixCommand报异常后如何处理—旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法

@Slf4j @Service public class StudentServiceImpl extends ServiceImpl implements StudentService {

  1. @Autowired
  2. private BizClient bizClient;
  3. @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
  4. @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")
  5. })
  6. @Override
  7. public String istimeout(Integer time) {

// int a = 1/0; List re = bizClient.timeout(time); log.info(“{}”,re); return “你好没有超时:”+re.toString(); }

  1. //善后方法
  2. public String paymentTimeOutFallbackMethod(Integer time){
  3. return "你好已超时,请稍后再试,o(╥﹏╥)o";
  4. }

}

  1. - 6.controller

@RestController @RequestMapping(“/hystrix”) @RequiredArgsConstructor(onConstructor = @__(@Autowired)) @Slf4j public class StudentController { private final StudentService studentService;

// hystrix @GetMapping(“timeout/{time}”) public String timeout(@PathVariable(“time”) Integer time) throws InterruptedException { Long cur = System.currentTimeMillis(); String re = studentService.istimeout(time); Long las = System.currentTimeMillis(); log.info(“耗时:{}”, las-cur); return re; } }

  1. ### Hystrix之全局服务降级DefaultProperties
  2. **改造serviceImpl**<br />[DefaultProperties ](/DefaultProperties )

@Slf4j @Service @DefaultProperties(defaultFallback = “payment_Global_FallbackMethod”) // 全局服务降级 public class StudentServiceImpl extends ServiceImpl implements StudentService {

  1. @Autowired
  2. private BizClient bizClient;

/ @HystrixCommand(fallbackMethod = “paymentTimeOutFallbackMethod”,commandProperties = { @HystrixProperty(name=”execution.isolation.thread.timeoutInMilliseconds”,value=”1500”) })/ @HystrixCommand//用全局的fallback方法 @Override public String istimeout(Integer time) { // int a = 1/0; List re = bizClient.timeout(time); log.info(“{}”,re); return “你好没有超时:”+re.toString(); }

  1. //善后方法 HystrixCommand
  2. public String paymentTimeOutFallbackMethod(Integer time){
  3. return "你好已超时或出错了,请稍后再试,o(╥﹏╥)o";
  4. }
  5. // 下面是全局fallback方法
  6. public String payment_Global_FallbackMethod()
  7. {
  8. return "Global异常处理信息,请稍后再试,/(ㄒoㄒ)/~~";
  9. }

}

  1. ### Hystrix之通配服务降级FeignFallback
  2. - RemoteHystrix 实现 BizClient,进行熔断处理

@Component public class RemoteHystrix implements BizClient {

  1. @Override
  2. public List<StudentEntity> selectStus() {
  3. System.out.println("熔断: selectStus");
  4. List<StudentEntity> studentEntities = new ArrayList<>();
  5. StudentEntity st = new StudentEntity();
  6. st.setName("error");
  7. studentEntities.add(st);
  8. return studentEntities;
  9. }
  10. @Override
  11. public List<StudentEntity> timeout(Integer time) {
  12. List<StudentEntity> studentEntities = new ArrayList<>();
  13. StudentEntity st = new StudentEntity();
  14. st.setName("error");
  15. studentEntities.add(st);
  16. System.out.println("熔断: timeout");
  17. return studentEntities;
  18. }

}

  1. - 修改BizClient 增加fallback = RemoteHystrix.class

@FeignClient(name=”zds-egg-biz”, fallback = RemoteHystrix.class) // feign //@FeignClient(name=”zds-egg-biz”) // hystrix @Component public interface BizClient {

  1. @GetMapping("selectStus")
  2. List<StudentEntity> selectStus();
  3. // hystrix
  4. @GetMapping("timeout/{time}")
  5. List<StudentEntity> timeout(@PathVariable("time") Integer time);

}

  1. - 修改servicceImpl

@Slf4j @Service public class StudentServiceImpl extends ServiceImpl implements StudentService {

  1. @Autowired
  2. private BizClient bizClient;
  3. @Override
  4. public String istimeout(Integer time) {

// int a = 1/0; List re = bizClient.timeout(time); log.info(“{}”,re); return re.toString(); }

}

```