天天看点

手把手学习springcloudalibaba:❤️‍服务熔断降级Hystrix的实战总结,学习完保你不在懵逼❤️‍Hystrix简介服务异常Hystrix停更 Hystrix实战总结

通过我前面章节的学习,大家应该可以利用Springcloud搭建一个基本的微服务架构。对于高可用的分布式架构,能够完成服务提供和调用是不够的,为了使我们的服务更加健壮,我们还希望服务有抵挡异常的能力和自我修复的能力,比如服务调用超时、运行时异常、宕机等情况下,我们的系统依然可以对用户提供友好可用的服务。这些是如何做到的,那么我们来一起学习下Hystrix,俗称“豪猪哥”。

Hystrix简介

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

Hystrix主要功能指:

  • 服务降级
  • 服务熔断
  • 服务限流

Hystrix通过上述三个功能,在服务异常情况下,保证服务调用方可以获取到符合预期的结果,而不是直接展示服务器异常,避免拖垮调用方,防止雪崩效应的出现。

服务雪崩:

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

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

通常当发现一个模块下的某个实例失败后,这时候这个模块依然还会接收流量,然后这个有问题的模块还调用了其他的模块,这样就会发生级联故障,或者叫雪崩。

服务异常

通常我们所说的异常主要分为如下三类:
  • 运行时异常
  • 超时
  • 宕机
这三类异常大家都可以做到见名知意,我就不展开说明了。后面在实战环节,我会讲如何根据这些异常做服务降级和熔断处理。

Hystrix停更 

目前Netflix公司宣布对Hystrix停更,进入维护阶段。但是它的设计思想非常先进和完善,出道即巅峰,其他替代品都是在它的基础上设计和加强。它非常优秀,在各大公司应用广泛,所以我还是要讲一下它在项目中如何使用,后续我也会讲解下,我们的国产替代品--阿里开源的Sentinel。 

Sentinel的使用比Hysrix更方便快捷,Hystrix真正运行起来需要启动一堆小组件,实时监控也需要临时配置,比较麻烦,很多同学可能因为其复杂的流程而很难入门,只要你用起来后,还是很简单的。所以大家在新起项目的时候,建议直接使用alibaba SpringCloud的相关组件,一次引入方便快捷。

Hystrix实战

我们可以引入Hystrix的依赖库,直接使用相应注解使服务具备处理异常的能力,也可以通过引入图形化组件HystrixDashboard做接口的实时状态监控。

服务降级实战

服务降级就是只服务调用出现异常,比如运行时异常、超时、宕机情况时,快速返回事先定义好的返回结果,防止服务调用方因服务提供方出问题被拖死。
  • 新建两个Module,分别是服务生产者和消费者。如何构建参考我以前的文章
  • 生产者和消费者的pom文件都要引入Hystrix的jar包依赖
<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
           
  • 修改消费者yml文件,服务调用使用OpenFeign,所以要开启feign的hystrix功能。(这里是不是看着很别扭,因为OpenFeign是从Feign而来,所以沿用很多feign的配置。),服务生产者不需要这个配置。
feign:
  hystrix:
    enabled: true
           
  • 修改启动类,开启Hystrix的配置,使用@EnableHystrix注解
/**
*服务生产者
*/
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
public class HystrixApplication8001 {
    public static void main(String[] args) {
        SpringApplication.run(HystrixApplication8001.class,args);
    }
}

/**
*服务消费者
*/
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix
public class HystrixApplication8080 {
    public static void main(String[] args) {
        SpringApplication.run(HystrixApplication8080.class,args);
    }
}
           
  • 修改业务类,服务生产者和服务消费者使用Hysrix的方式略有不同。服务提供方一般加在controller上;服务消费者一般加在Service上,因为再Service上使用Feign封装服务调用。说重点:在实际代码编写过程中,我们在服务提供方和服务消费方都要加上降级逻辑,因为存在多级调用的情况,即存在功能1用A服务,A服务调用B服务,B服务又调用C服务;功能2调用B;在这两个功能请求中B服务既是服务提供方,又是服务消费方,所以只在消费方就不合理了。原则上两边都加上,在服务治理时,通过日志监控可以快速定位是哪个服务出的问题。
  • 服务生产者代码实现
@RestController
@RequestMapping("/payment")
public class PayMentController {
    @Autowired
    private PaymentService paymentService;

    @Value("${server.port}")
    private String port;



    @GetMapping("/getPayment/{id}")
    @HystrixCommand(fallbackMethod = "getPaymentOut", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public MsgResponseBody getPayment(@PathVariable("id") Long id) {
        Payment payment = paymentService.getById(id);
        String a = "查询"+port+"成功";
        String code ="200";
            return new MsgResponseBody().setMsg(a).setResultCode(code).setData(payment);
    }

    /**
    *
    *跟getPayment对应的降级方法
    */
    public MsgResponseBody getPaymentOut(Long id) {
        System.out.println("服提供方降级: "+id);
        MsgResponseBody msgResponseBody = new MsgResponseBody();
        msgResponseBody.setMsg("服务提供方降级");
        msgResponseBody.setResultCode("500");
        msgResponseBody.setData(null);
        return msgResponseBody;

    }
}
           
  • 服务消费者代码实现
/**
*
*服务调用的Service
*/
@Component
@FeignClient(value = "CLOUD-HYSTRIX-PAYMENT-SERVICE", fallback = PaymentFeignFallbackService.class)
public interface PaymentFeignService {
    @GetMapping("/payment/getPayment/{id}")
    public MsgResponseBody getById(@PathVariable("id") Long id);
}


/**
*
*服务降级采用统一返回,
*/
@Component
public class PaymentFeignFallbackService implements PaymentFeignService{
    @Override
    public MsgResponseBody getById(Long id) {
        System.out.println("提供方服务降级");
        MsgResponseBody msgResponseBody = new MsgResponseBody();
        msgResponseBody.setMsg("提供方服务降级");
        msgResponseBody.setResultCode("500");
        msgResponseBody.setData(null);
        return msgResponseBody;
    }
}


@RestController
@RequestMapping("/consumer")
public class OpenFeignConsumerController {
    @Resource
    private PaymentFeignService paymentFeignService;

    @GetMapping("/getPayment/{id}")
    @HystrixCommand(fallbackMethod = "fallBack", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public MsgResponseBody getPaymet(@PathVariable("id") Long id){
        int age = 1/0;
        return paymentFeignService.getById(id);
    }

    /**
    *
    *消费方本身出现问题时服务降级的快速返回
    */
    public MsgResponseBody fallBack(){
        System.out.println("调用方服务降级");
        MsgResponseBody msgResponseBody = new MsgResponseBody();
        msgResponseBody.setMsg("调用方服务降级");
        msgResponseBody.setResultCode("500");
        msgResponseBody.setData(null);
        return msgResponseBody;
    }
}
           

服务熔断实战

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

参数配置

使用@HystrixCommand注解,涉及的参数如下:
  • 是否开启断路器,必须要设置成true
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
  • 请求次数
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
  • 时间窗口期
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
  • 失败率达到多少后跳闸

@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")

打开断路器之后,在10秒内,请求10次,出现60%失败率的时候,触发断路器生效,服务开始做降级处理,当失败率低于60%时,服务调用开始恢复,正常返回结果。 

总结

重点:

服务讲解熔断我们使用的都是@HystrixCommand注解,是方法级注解,加在哪个方法上,哪个方法就生效。通常都加在Controller上,即服务的入口上,这样就能覆盖求情的整个生命周期。

扫码请关注

手把手学习springcloudalibaba:❤️‍服务熔断降级Hystrix的实战总结,学习完保你不在懵逼❤️‍Hystrix简介服务异常Hystrix停更 Hystrix实战总结

同时也欢迎大家添加个人微信【shishuai860505】,我拉大家进我的读者交流群。

手把手学习springcloudalibaba:❤️‍服务熔断降级Hystrix的实战总结,学习完保你不在懵逼❤️‍Hystrix简介服务异常Hystrix停更 Hystrix实战总结

继续阅读