• 【SpringCloud构建微服务系列】学习断路器Hystrix


    一、Hystrix简介

    在微服务架构中经常包括多个服务层,比如A为B提供服务,B为C和D提供服务,如果A出故障了就会导致B也不可用,最终导致C和D也不可用,这就形成了雪崩效应
    所以为了应对这种情况,我们就需要一种容错机制,该机制需要实行以下两点:

    1. 为网络请求设置超时,以便尽快释放资源
    2. 使用断路器模式,就像家里的电闸一样,如果电流过大就会立刻跳闸以保护电路防止发生火灾。当请求失败率达到一定的阈值,断路器就会打开,不会再请求依赖的服务。
      Hystrix就是这样设计的,以实现容错处理,文章代码都可以在我的github下载。

    二、通用方式整合Hystrix

    1. 复制项目microservice-consumer-movie-ribbon改为microservice-consumer-movie-ribbon-hystrix
    2. 添加所需依赖
    <dependency>
       		<groupId>org.springframework.cloud</groupId>
       		<artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>
    
    1. 在启动类添加注解 @EnableHystrix 或者 @EnableCircuitBreaker以启用
    2. 修改MovieController代码,让findById方法具备容错能力
    @RestController
    public class MovieController {
    
        @Autowired
        private LoadBalancerClient loadBalancerClient;
    
        @Autowired
        private RestTemplate restTemplate;
    
        private static final Logger logger = LoggerFactory.getLogger(MovieController.class);
    
    
        @HystrixCommand(fallbackMethod = "findByIdFallBack")
        @GetMapping("/user/{id}")
        public User findById(@PathVariable Long id){
            //microservice-provider-user是虚拟主机名,默认和服务名称一致
            //不能包括"_"之类的字符,否则Ribbon在调用时会报异常
            return this.restTemplate.getForObject("http://microservice-provider-user/"+id,User.class);
        }
    
        public User findByIdFallBack(Long id){
            User user = new User();
            user.setId(-1L);
            user.setAge(0);
            user.setBalance(BigDecimal.ZERO);
            user.setName("默认用户");
            user.setUsername("默认用户");
            return user;
        }
    }
    

    这里考虑篇幅就不细说 @HystrixCommand注解的属性配置问题了。

    测试

    1.分别启动服务microservice-discovery-eurekamicroservice-provider-usermicroservice-consumer-movie-ribbon-hystrix
    2.游览器访问http://localhost:8010/user/1获得如下结果

    {"id":1,"username":"xxx","name":"zhangsan","age":22,"balance":100}

    3.关掉服务microservice-provider-user再重新请求,获得如下结果。

    {"id":-1,"username":"默认用户","name":"默认用户","age":0,"balance":0}

    说明服务不可用时,进入到了回退方法。
    为服务引入SpringBoot Actuator,再访问/health端点可以查看断路器状态,不过我尝试失败了。

    三、Feign使用Hystrix

    3.1为Feign添加回退

    1.复制项目microservice-consumer-movie-feign改为microservice-consumer-movie-feign-hystrix-fallback,注意pom文件spring-cloud-starter-eureka 和 spring-cloud-starter-feign 已经过时
    2.Feign默认已经整合了Hystrix,所以不需要额外引入依赖。
    3.将之前的UserFeignClient接口修改为如下

    1. /** 
    2. * @author ship 
    3. * @Description Feign的fallback测试 
    4. * 使用@FeignClient的fallback属性指定回退类 
    5. * @Date: 2018-07-17 13:25 
    6. */ 
    7. @FeignClient(name = "microservice-provider-user",fallback = FeignClientFallback.class) 
    8. public interface UserFeignClient
    9.  
    10. @RequestMapping(value = "/{id}",method = RequestMethod.GET) 
    11. User findById(@PathVariable("id") Long id)
    12.  
    13.  
    14. /** 
    15. * 回退类FeignClientFallback需实现Feign Client接口 
    16. */ 
    17. @Component 
    18. class FeignClientFallback implements UserFeignClient
    19. @Override 
    20. public User findById(Long id)
    21. User user = new User(); 
    22. user.setId(-1L); 
    23. user.setUsername("默认用户"); 
    24. return user; 

    开始测试
    1.按顺序启动服务microservice-discovery-eurekamicroservice-provider-usermicroservice-consumer-movie-feign-hystrix-fallback
    2.访问http://localhost:8010/user/1可获得正常结果
    3.停止microservice-provider-user后再次访问获得如下结果说明已经成功了。
    {"id":-1,"username":"默认用户","name":"默认用户","age":0,"balance":0}
    如果你遇到了404问题,可能是因为从Spring Cloud Dalston开始,Feign默认是不开启Hystrix的。所以需要在application.yml文件上添加如下内容。
    enter description here
    注意单词不要拼写错,我就是因为enabled写成了enable折腾了半天。。。。

    3.2通过fallback factory检查回退原因

    1.复制项目microservice-consumer-movie-feign改为microservice-consumer-movie-feign-hystrix-fallback-factory
    2.修改UserFeignClient接口

    1. /** 
    2. * @author ship 
    3. * @Description Feign的fallback测试 
    4. * 使用@FeignClient的fallback属性指定回退类 
    5. * @Date: 2018-07-17 13:25 
    6. */ 
    7. @FeignClient(name = "microservice-provider-user",fallbackFactory = FeignClientFallbackFactory.class) 
    8. public interface UserFeignClient
    9.  
    10. @RequestMapping(value = "/{id}",method = RequestMethod.GET) 
    11. User findById(@PathVariable("id") Long id)
    12.  
    13.  
    14. /** 
    15. * 通过FallbackFactory检查回退原因 
    16. */ 
    17. @Component 
    18. class FeignClientFallbackFactory implements FallbackFactory<UserFeignClient>
    19.  
    20. private static final Logger logger = LoggerFactory.getLogger(FeignClientFallbackFactory.class); 
    21.  
    22. /** 
    23. * 还可以根据不同的异常类型返回不同的结果 
    24. * @param cause 
    25. * @return 
    26. */ 
    27. @Override 
    28. public UserFeignClient create(Throwable cause)
    29. return new UserFeignClient() { 
    30.  
    31. @Override 
    32. public User findById(Long id)
    33. //日志最好放在各个fallback方法中,而不是create方法中 
    34. //否则在引用启动时,就会打印该日志 
    35. logger.info("fallback reason was:",cause); 
    36. User user = new User(); 
    37. user.setId(-1L); 
    38. user.setUsername("默认用户"); 
    39. return user; 
    40. }; 

    还可以根据不同的异常类型,返回不同的结果。
    测试过程跟上面差不多,多了个查看日志的过程,在此省略。

    四、Hystrix的监控

    Hystrix提供了实时的监控,比如每秒执行的请求数,成功数等,这些对于查看服务的状态都很有意义。
    使用Hystrix的hystrix-metrics-event-stream(spring-cloud-starter-hystrix已经包括)模块后,再添加spring-boot-starter-actuator就可以使用/hystrix.stream端点获得监控信息了。


    之前的项目microservice-consumer-movie-ribbon-hystrix已经具备监控的能力,做个小测试。
    1.依次启动microservice-discovery-eurekamicroservice-provider-usermicroservice-consumer-movie-ribbon-hystrix
    2.访问http://localhost:8010/hystrix.stream,可以看到游览器一直处于请求状态且窗口空白,这是因为我们没有请求@HystrixCommand标注的方法,还没有数据产生。
    3.先访问http://localhost:8010/user/1后再次访问http://localhost:8010/hystrix.stream,则可看到如下结果。
    enter description here

    Feign项目的监控

    1.复制项目microservice-consumer-movie-feign-hystrix-fallback修改为microservice-consumer-movie-feign-hystrix-fallback-stream
    2.添加spring-cloud-starter-hystrix依赖,确保存在actuator的包

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

    3.在启动类上添加注解@EnableCircuitBreaker就可以了。

    五、使用Hystrix Dashboard数据可视化

    可以使用Hystrix Dashboard,让监控数据可视化,图形化。
    1.创建一个springboot项目,artifactId为microservice-hystrix-dashboard,并添加依赖

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

    2.启动类添加 @EnableHystrixDashboard注解
    3.设置端口号为8030这样就可以了
    4.访问http://localhost:8030/hystrix,即可看到主页,如图。
    enter description here
    5.先进行之前的测试产生数据,再在URL输入http://localhost:8010/hystrix.stream并随便设置一个Title,点击最下方的按钮后即可看到。
    enter description here

    六、使用Turbine聚合监控数据

    6.1turbine简介

    一般每个微服务都会部署多个实例,Hystrix Dashboard每次只能查看单个的很不方便,turbine是一个聚合Hystrix监控数据的工具,
    它可以将所有 /hystrix.stream端点的数据聚合到一个组合的 /turbine.stream中,从而让集群的监控更加方便。

    6.2编写turbine项目

    代码见github

    6.3测试

    1.启动项目microservice-discovery-eureka
    2.启动项目microservice-provider-user
    3.启动项目microservice-consumer-movie-ribbon-hystrix
    4.启动项目microservice-consumer-movie-feign-hystrix-fallback-stream
    5.启动项目microservice-hystrix-turbine
    6.启动项目microservice-hystrix-dashboard
    7.访问http://localhost:8010/user/1,让microservice-consumer-movie-ribbon-hystrix服务产生监控数据
    8.访问http://localhost:8020/user/1,让microservice-consumer-movie-feign-hystrix-fallback-stream服务产生监控数据
    9.打开dashboard首页,在URL一栏输入http://localhost:8031/turbine.stream,随意指定一个title,再点击monitor stream按钮后即可看到多个服务的监控数据。

    总结

    其实Hystrix还有很多地方没有讲,比如@HystrixCommand的属性配置问题,Hystrix的线程隔离策略和传播上下文等,第一次用markdown编辑器感觉还不错。

  • 相关阅读:
    C# Stream篇(—) -- Stream基类-----转载
    C# Stream篇(三) -- TextWriter 和 StreamWriter---转载
    C#文件过滤器filter---转载
    微信列表展示与详情页
    关于微信表单添加与图片上传
    登录的php代码 接口开发
    文章列表与点赞的一些功能实现 以及详情页点赞、取消赞操作
    Linux 简单命令总结
    微信小程序实现登录功能 (第一种模式)
    201509-1 数列分段 Java
  • 原文地址:https://www.cnblogs.com/2YSP/p/9344552.html
Copyright © 2020-2023  润新知