天天看点

服务降级以及熔断的理解hystrix

hystrix

可以参考一下这个链接

https://blog.csdn.net/guwei9111986/article/details/51649240/

  • Hystrix是一个用于处理分布式系统的延迟和容错的开源库, 在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,
  • Hystrix能够保证在一个依赖出问题的情况下, 不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
  • ”断路器”本身是-种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝) ,向调用方返回-个符合预期的、可处理的备选响应(FalBack) ,而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
  • 对于*** 降级与熔断 ***的区别,我觉得可以额这样理解
    • 降级是对于整体的负荷的考虑,降级是没有办法实现熔断的,也就是说当有多个线程访问一个服务的时候,服务变卡了,可以用设置超时时间来降级;
    • 但是这些线程还是不断的冲击这个服务,过载或者这个服务压力很大,但是没人管,所以这个时候就会有熔断出现,熔断这个节点的服务。此后这些线程再去访问这个服务,就可以直接执行fallback方法,不能执行服务里面的方法。随后慢慢恢复调用的链路(这也是为了防止A调用B调用C,这种服务出现错误,雪崩的情况出现)
  • (*** 如果不对请多多指教哦 ***)

hystrix重要概念

服务降级

  • 服务降级(fallback)
    • 服务器忙,请稍候再试,不让客户端等待并立刻返回一个友好提示,fallback
    • 哪些情况会触发降级
      • 程序运行异常
        • 超时
        • 服务熔断触发服务降级
        • 线程池/信号量打满也会导致服务降级
    • 服务降级的三种方法( 降级的优先级从方法开始就近原则 )
      • 1、单独对某个方法降级,实例(hytrix+openFeign)
      @GetMapping("/consumer/payment/hystrix/timeout2/{id}")
       @HystrixCommand(fallbackMethod="paymentTimeOutFallbackMethod",
                       commandProperties = {
                				  @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")  //3秒钟以内就是正常的业务逻辑
          })
          public String paymentInfo_TimeOut2(@PathVariable("id") Integer id){
      //        int x=10/0;
              //如果服务发生了类似10/0的异常,也会出现报错
              //调用服务端方法
              String result = paymentHystrixService.paymentInfo_TimeOut(id);
              return result;
          }
      
          //兜底方法
          public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id){
              return "我是消费者80,对付支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,(┬_┬)";
          }
                 
      • 2、全局降级(单独降级优先级更高),对那些没有特别指明fallback的方法,我们可以用全局的降级方法来对他进行降级,只要再在类前加上注解@DefaultProperties(defaultFallback = “payment_Global_FallbackMethod”),并对要降级的方法加上@HytrixCommand
      • @RestController
        //指定全局的服务降级
        @DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
        @Slf4j
        public class OrderHystrixController {
        
            @Resource
            private PaymentHystrixService paymentHystrixService;
        
            @GetMapping("/customer/payment/hystrix/ok/{id}")
            public String paymentInfo_OK(@PathVariable("id") Integer id){
                return paymentHystrixService.paymentInfo_OK(id);
            }
        
        
        
            @HystrixCommand
            @GetMapping("/customer/payment/hystrix/timeout/{id}")
            public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
                return paymentHystrixService.paymentInfo_TimeOut(id);
            }
        
            //全局的fallback方法
            public String payment_Global_FallbackMethod(){
                return "global处理异常,请检查自己,(┬_┬)";
            }
        
        }
                   
      • 3、对调用的服务的方法进行降级
        • 当前调用的服务方法有可能会出错(例如宕机等等),当出错的时候我们应该要有降级的方法,
        • 实现feign的接口
        • @Component
          public class PaymentFallbackService implements PaymentHystrixService {
              @Override
              public String paymentInfo_OK(Integer id) {
                  return "PaymentFallbackService fall back-paymentInfo_OK o(╥﹏╥)o --->";
              }
          
              @Override
              public String paymentInfo_TimeOut(Integer id) {
                  return "PaymentFallbackService fall back-paymentInfo_TimeOut o(╥﹏╥)o --->";
              }
          }
                     
          在feign接口的注解feign的注解中加上一个属性
          @Component
          //这里的fallback属于是对调用对方服务的时候宕机的话进行fallback处理
          @FeignClient(value = "cloud-provider-hystrix-payment",fallback = PaymentFallbackService.class)
          
          public interface PaymentHystrixService {
          
              @GetMapping("/payment/hystrix/ok/{id}")
              public String paymentInfo_OK(@PathVariable("id") Integer id);
          
          
              @GetMapping("/payment/hystrix/timeout/{id}")
              public String paymentInfo_TimeOut(@PathVariable("id") Integer id);
          
          }
                     

服务熔断

  • 熔断机制概述熔断机制概述

    熔断机制是应对雪崩效应的一-种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。*** 当检测到该节点微服务调用响应正常后,恢复调用链路。***

  • 在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,

    当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是@HystrixCommand.

  • 测试熔断–>在提供者端(provider)
  • service端
    @Service
    @Slf4j
    
    public class PaymentService {
        
    
        //服务熔断
        @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
                @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),  //是否开启断路器
                @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),   //请求次数
                @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),  //时间范围
                @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"), //失败率达到多少后跳闸
        })
        public String paymentCircuitBreaker(@PathVariable("id") Integer id){
            if (id < 0){
                throw new RuntimeException("*****id 不能负数");
            }
            String serialNumber = IdUtil.simpleUUID();
    
            return Thread.currentThread().getName()+"\t"+"调用成功,流水号:"+serialNumber;
        }
        	
        public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){
            return "id 不能负数,请稍候再试,(┬_┬)/~~     id: " +id;
        }
    
    }
               
  • controller端
  • @RestController
    @Slf4j
    public class PaymentController {
        @Resource
        private PaymentService paymentService;
    
        @Value("${server.port}")
        private String serverPort;
    //服务熔断
    //===服务熔断
    //如果调用service的时候负数太多,达到阀值就会进行熔断打开,等到慢慢正确(即正确次数变多),才进行熔断关闭
    @GetMapping("/payment/circuit/{id}")
    public String paymentCircuitBreaker(@PathVariable("id") Integer id){
        String result = paymentService.paymentCircuitBreaker(id);
        log.info("*******result:"+result);
        return result;
    }