• Spring Cloud 入门教程(七): 熔断机制 -- 断路器


    对断路器模式不太清楚的话,可以参看另一篇博文:断路器(Curcuit Breaker)模式,下面直接介绍Spring Cloud的断路器如何使用。

    SpringCloud Netflix实现了断路器库的名字叫Hystrix. 在微服务架构下,通常会有多个层次的服务调用. 下面是微服架构下, 浏览器端通过API访问后台微服务的一个示意图:

    一个微服务的超时失败可能导致瀑布式连锁反映,下图中,Hystrix通过自主反馈实现的断路器, 防止了这种情况发生。

     图中的服务B因为某些原因失败,变得不可用,所有对服务B的调用都会超时。当对B的调用失败达到一个特定的阀值(5秒之内发生20次失败是Hystrix定义的缺省值), 链路就会被处于open状态, 之后所有所有对服务B的调用都不会被执行, 取而代之的是由断路器提供的一个表示链路open的Fallback消息.  Hystrix提供了相应机制,可以让开发者定义这个Fallbak消息.

    open的链路阻断了瀑布式错误, 可以让被淹没或者错误的服务有时间进行修复。这个fallback可以是另外一个Hystrix保护的调用, 静态数据,或者合法的空值. Fallbacks可以组成链式结构,所以,最底层调用其它业务服务的第一个Fallback返回静态数据.

    下面,进入正题,在之前的两HELLO WORLD服务集群中加入断路器, 防止其中一个Hello world挂掉后, 导致系统发生连锁超时失败。

    1. 在maven工程(前面章节中介绍的Ribbon或者Feign工程)的pom.xml中添加hystrix库支持断路器

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>

    2. 在Ribbon应用中使用断路器

    1). 在Spring Boot启动类上添加@EnableCircuitBreaker注解

    复制代码
    1 @SpringBootApplication
    2 @EnableDiscoveryClient
    3 @EnableCircuitBreaker
    4 public class ServiceRibbonApplication {
    5 
    6     public static void main(String[] args) {
    7         SpringApplication.run(ServiceRibbonApplication.class, args);
    8     }
    。。。 。。。
    复制代码

    2). 用@HystrixCommand注解标注访问服务的方法

    复制代码
     1 @Service
     2 public class HelloService {
     3     @Autowired RestTemplate restTemplate;
     4 
     5     @HystrixCommand(fallbackMethod = "serviceFailure")
     6     public String getHelloContent() {
     7         return restTemplate.getForObject("http://SERVICE-HELLOWORLD/",String.class);
     8     }
     9 
    10     public String serviceFailure() {
    11         return "hello world service is not available !";
    12     }
    13 }
    复制代码

    @HystrixCommand注解定义了一个断路器,它封装了getHelloContant()方法, 当它访问的SERVICE-HELLOWORLD失败达到阀值后,将不会再调用SERVICE-HELLOWORLD, 取而代之的是返回由fallbackMethod定义的方法serviceFailure()。@HystrixCommand注解定义的fallbackMethod方法,需要特别注意的有两点:

    第一,  fallbackMethod的返回值和参数类型需要和被@HystrixCommand注解的方法完全一致。否则会在运行时抛出异常。比如本例中,serviceFailure()的返回值和getHelloContant()方法的返回值都是String。

    第二,  当底层服务失败后,fallbackMethod替换的不是整个被@HystrixCommand注解的方法(本例中的getHelloContant), 替换的只是通过restTemplate去访问的具体服务。可以从中的system输出看到, 即使失败,控制台输出里面依然会有“call SERVICE-HELLOWORLD”。

    启动eureka服务,只启动两个Helloworld服务,然后中断其中一个(模拟其中一个微服务挂起),访问http://localhost:8901/然后刷新, 由于有负载均衡可以看到以下两个页面交替出现。可以看到第二个被挂起的服务,被定义在Ribbon应该里面的错误处理方法替换了。

             

    4. 在Feign应用中使用断路器

    1). Feign内部已经支持了断路器,所以不需要想Ribbon方式一样,在Spring Boot启动类上加额外注解

    2). 用@FeignClient注解添加fallback类, 该类必须实现@FeignClient修饰的接口。

    1 @FeignClient(name = "SERVICE-HELLOWORLD", fallback = HelloWorldServiceFailure.class)
    2 public interface HelloWorldService {
    3     @RequestMapping(value = "/", method = RequestMethod.GET)
    4     public String sayHello();
    5 }

    3). 创建HelloWorldServiceFailure类, 必须实现被@FeignClient修饰的HelloWorldService接口。注意添加@Component或者@Service注解,在Spring容器中生成一个Bean

    复制代码
    1 @Component
    2 public class HelloWorldServiceFailure implements HelloWorldService {
    3     @Override
    4     public String sayHello() {
    5         System.out.println("hello world service is not available !");
    6         return "hello world service is not available !";
    7     }
    8 }
    复制代码

    4). Spring Cloud之前的Brixton版本中,Feign是缺省是自动激活了断路器的,但最近的Dalston版本已经将缺省配置修改为禁止。

    原因参见:  https://github.com/spring-cloud/spring-cloud-netflix/issues/1277, 这一点要注意。所以要在Feign中使用断路器, 必须在application.yml中添加如下配置:

    feign:
       hystrix:
         enabled: true

    5). 启动Feign应用, 访问http://localhost:8902/hello, 可以一看到和Ribbon一样的效果。

  • 相关阅读:
    关于CSS/Grid Layout实例的理解
    关于对CSS position的理解
    接上一条博客
    搬迁声明
    自动化测试流程
    浏览器测试app-H5页面使用appium实现自动化
    RSA加密算法坑:pyasn1-error-when-reading-a-pem-string
    parameter/argument, Attribute/Property区别
    本地mysql用Navicat链接报错 Authentication plugin 'caching_sha2_password' cannot be loaded
    mysql安装忘记root密码,初始化密码
  • 原文地址:https://www.cnblogs.com/7788IT/p/11324290.html
Copyright © 2020-2023  润新知