• Spring Cloud构建微服务架构(三)断路器


    在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。

    Netflix Hystrix

    在Spring Cloud中使用了Hystrix 来实现断路器的功能。Hystrix是Netflix开源的微服务框架套件之一,该框架目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能。

    下面我们来看看如何使用Hystrix。

    准备工作

    在开始加入断路器之前,我们先拿之前构建两个微服务为基础进行下面的操作,主要使用下面几个工程

      • eureka-server工程:服务注册中心,端口1111
      • compute-service工程:服务单元,端口2222
      • eureka-ribbon:通过ribbon实现的服务单元,依赖compute-service的服务,端口3333
      • eureka-feign:通过feign实现的服务单元,依赖compute-service的服务,端口3333
      • Ribbon中引入Hystrix

        • 依次启动eureka-server、compute-service、eureka-ribbon工程
        • 访问http://localhost:1111/可以看到注册中心的状态
        • 访问http://localhost:3333/add,调用eureka-ribbon的服务,该服务会去调用compute-service的服务,计算出10+20的值,页面显示30
        • 关闭compute-service服务,访问http://localhost:3333/add,我们获得了下面的报错信息
        Whitelabel Error Page
         
        This application has no explicit mapping for /error, so you are seeing this as a fallback.
         
        Sat Jun 25 21:16:59 CST 2016
        There was an unexpected error (type=Internal Server Error, status=500).
        I/O error on GET request for "http://COMPUTE-SERVICE/add?a=10&b=20": Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect

        • pom.xml中引入依赖hystrix依赖
        <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>

        • 在eureka-ribbon的主类RibbonApplication中使用@EnableCircuitBreaker注解开启断路器功能:
        @SpringBootApplication
        @EnableDiscoveryClient
        @EnableCircuitBreaker
        public class RibbonApplication {
         
        @Bean
        @LoadBalanced
        RestTemplate restTemplate() {
        return new RestTemplate();
        }
         
        public static void main(String[] args) {
        SpringApplication.run(RibbonApplication.class, args);
        }
         
        }

        • 改造原来的服务消费方式,新增ComputeService类,在使用ribbon消费服务的函数上增加@HystrixCommand注解来指定回调方法。
        @Service
        public class ComputeService {
         
        @Autowired
        RestTemplate restTemplate;
         
        @HystrixCommand(fallbackMethod = "addServiceFallback")
        public String addService() {
        return restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody();
        }
         
        public String addServiceFallback() {
        return "error";
        }
         
        }

        • 提供rest接口的Controller改为调用ComputeService的addService
        @RestController
        public class ConsumerController {
         
        @Autowired
        private ComputeService computeService;
         
        @RequestMapping(value = "/add", method = RequestMethod.GET)
        public String add() {
        return computeService.addService();
        }
         
        }

        更多关于Hystrix的使用可参考How To Use

        Feign使用Hystrix

        注意这里说的是“使用”,没有错,我们不需要在Feigh工程中引入Hystix,Feign中已经依赖了Hystrix,我们可以在未做任何改造前,尝试下面你的操作:

        • 依次启动eureka-server、compute-service、eureka-feign工程
        • 访问http://localhost:1111/可以看到注册中心的状态
        • 访问http://localhost:3333/add,调用eureka-feign的服务,该服务会去调用compute-service的服务,计算出10+20的值,页面显示30
        • 关闭compute-service服务,访问http://localhost:3333/add,我们获得了下面的报错信息
        Whitelabel Error Page
         
        This application has no explicit mapping for /error, so you are seeing this as a fallback.
         
        Sat Jun 25 22:10:05 CST 2016
        There was an unexpected error (type=Internal Server Error, status=500).
        add timed-out and no fallback available.

        如果您够仔细,会发现与在ribbon中的报错是不同的,看到add timed-out and no fallback available这句,或许您已经猜到什么,看看我们的控制台,可以看到报错信息来自hystrix-core-1.5.2.jar,所以在这个工程中,我们要学习的就是如何使用Feign中集成的Hystrix。

        • 使用@FeignClient注解中的fallback属性指定回调类
        @FeignClient(value = "compute-service", fallback = ComputeClientHystrix.class)
        public interface ComputeClient {
         
        @RequestMapping(method = RequestMethod.GET, value = "/add")
        Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b);
         
        }

        • 创建回调类ComputeClientHystrix,实现@FeignClient的接口,此时实现的方法就是对应@FeignClient接口中映射的fallback函数。
        @Component
        public class ComputeClientHystrix implements ComputeClient {
         
        @Override
        public Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b) {
        return -9999;
        }
         
        }

        • 再用之前的方法验证一下,是否在compute-service服务不可用的情况下,页面返回了-9999。
        • 关于Feign的更多使用方法可参考:Feign
  • 相关阅读:
    关于数论的一些总结
    gym101431B
    4.29训练题解
    hdu4347
    5.13训练的一些题解
    5.20训练的一些题解
    hdu4796
    hdu5984
    bzoj1941 hdu5992
    hdu4307
  • 原文地址:https://www.cnblogs.com/ilinuxer/p/6538125.html
Copyright © 2020-2023  润新知