一、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-eureka,microservice-provider-user,microservice-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. @RequestMapping(value = "/{id}",method = RequestMethod.GET) 

  10. User findById(@PathVariable("id") Long id); 





  11. /** 

  12. * 回退类FeignClientFallback需实现Feign Client接口 

  13. */ 

  14. @Component 

  15. class FeignClientFallback implements UserFeignClient { 

  16. @Override 

  17. public User findById(Long id) { 

  18. User user = new User(); 

  19. user.setId(-1L); 

  20. user.setUsername("默认用户"); 

  21. return user; 





开始测试
1.按顺序启动服务microservice-discovery-eureka,microservice-provider-user,microservice-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文件上添加如下内容。

注意单词不要拼写错,我就是因为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. @RequestMapping(value = "/{id}",method = RequestMethod.GET) 

  10. User findById(@PathVariable("id") Long id); 





  11. /** 

  12. * 通过FallbackFactory检查回退原因 

  13. */ 

  14. @Component 

  15. class FeignClientFallbackFactory implements FallbackFactory<UserFeignClient>{ 


  16. private static final Logger logger = LoggerFactory.getLogger(FeignClientFallbackFactory.class); 


  17. /** 

  18. * 还可以根据不同的异常类型返回不同的结果 

  19. * @param cause 

  20. * @return 

  21. */ 

  22. @Override 

  23. public UserFeignClient create(Throwable cause) { 

  24. return new UserFeignClient() { 


  25. @Override 

  26. public User findById(Long id) { 

  27. //日志最好放在各个fallback方法中,而不是create方法中 

  28. //否则在引用启动时,就会打印该日志 

  29. logger.info("fallback reason was:",cause); 

  30. User user = new User(); 

  31. user.setId(-1L); 

  32. user.setUsername("默认用户"); 

  33. return user; 



  34. }; 





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

四、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,则可看到如下结果。

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,即可看到主页,如图。

5.先进行之前的测试产生数据,再在URL输入http://localhost:8010/hystrix.stream并随便设置一个Title,点击最下方的按钮后即可看到。

六、使用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编辑器感觉还不错。

【SpringCloud构建微服务系列】学习断路器Hystrix的更多相关文章

  1. 【SpringCloud构建微服务系列】微服务网关Zuul

    一.为什么要用微服务网关 在微服务架构中,一般不同的微服务有不同的网络地址,而外部客户端(如手机APP)可能需要调用多个接口才能完成一次业务需求.例如一个电影购票的手机APP,可能会调用多个微服务的接 ...

  2. 【SpringCloud构建微服务系列】分布式链路跟踪Spring Cloud Sleuth

    一.背景 随着业务的发展,系统规模越来越大,各微服务直接的调用关系也变得越来越复杂.通常一个由客户端发起的请求在后端系统中会经过多个不同的微服务调用协同产生最后的请求结果,几乎每一个前端请求都会形成一 ...

  3. 【SpringCloud构建微服务系列】Feign的使用详解

    一.简介 在微服务中,服务消费者需要请求服务生产者的接口进行消费,可以使用SpringBoot自带的RestTemplate或者HttpClient实现,但是都过于麻烦. 这时,就可以使用Feign了 ...

  4. 【SpringCloud构建微服务系列】使用Spring Cloud Config统一管理服务配置

    一.为什么要统一管理微服务配置 对于传统的单体应用而言,常使用配置文件来管理所有配置,比如SpringBoot的application.yml文件,但是在微服务架构中全部手动修改的话很麻烦而且不易维护 ...

  5. SpringCloud与微服务系列专栏

    一. 前置知识 学习SpringCloud之前需要具备和掌握如下框架和工具的使用:SpringMVC,Spring,Spring Boot,Mybatis,Maven,Git. SpringCloud ...

  6. SpringCloud 构建微服务架构-练习

    我使用的springboot的版本为2.0.2.RELEASE,这里概念性的东西我就不粘贴复制了,百度一下 都是 一.启动Eureka注册中心服务 1.新建springboot项目,pom.xml配置 ...

  7. Spring Cloud微服务系列文,Hystrix与Eureka的整合

    和Ribbon等组件一样,在项目中,Hystrix一般不会单独出现,而是会和Eureka等组件配套出现.在Hystrix和Eureka整合后的框架里,一般会用到Hystrix的断路器以及合并请求等特性 ...

  8. Spring Cloud微服务系列文,服务调用框架Feign

    之前博文的案例中,我们是通过RestTemplate来调用服务,而Feign框架则在此基础上做了一层封装,比如,可以通过注解等方式来绑定参数,或者以声明的方式来指定请求返回类型是JSON.    这种 ...

  9. 【微服务】之二:从零开始,轻松搞定SpringCloud微服务系列--注册中心(一)

    微服务体系,有效解决项目庞大.互相依赖的问题.目前SpringCloud体系有强大的一整套针对微服务的解决方案.本文中,重点对微服务体系中的服务发现注册中心进行详细说明.本篇中的注册中心,采用Netf ...

随机推荐

  1. bzoj4161 (k^2logn求线性递推式)

    分析: 我们可以写把转移矩阵A写出来,然后求一下它的特征多项式,经过手动计算应该是这样的p(x)=$x^k-\sum\limits_{i=1}^ka_i*x^{k-i}$ 根据Cayley-Hamil ...

  2. Linux 特殊文档说明

    目录 /usr/share/man 目录 /usr/share/doc /etc/passwd 文件 /etc/shadow 文件 /etc/group 文件 /usr/share/man 目录 当我 ...

  3. oracle 用户账户被锁处理

    一.以管理员身份登录 SQL> conn sys/sys as sysdba; (分号是必须的但是我是以system登录的所在这不应该写conn sys/sys as sysdba应该写conn ...

  4. 使用Android SwipeRefreshLayout了解Android的嵌套滑动机制

    SwipeRefreshLayout 是在Android Support Library, revision 19.1.0加入到support v4库中的一个下拉刷新控件,关于android的下拉刷新 ...

  5. SQL FULL OUTER JOIN 关键字

    SQL FULL OUTER JOIN 关键字 SQL FULL OUTER JOIN 关键字 FULL OUTER JOIN 关键字只要左表(table1)和右表(table2)其中一个表中存在匹配 ...

  6. python05-09

    一.lambda表达式 def f1(): return 123 f2 = lambda : 123 def f3 = (a1,a2): return a1+a2 f4 = lambda a1,a2 ...

  7. linux远程管理工具:putty

    使用QTP测试文件上传和目录做成是否成功,必须先将文件和目录下载到本地,再作比较.现在下载工具众多,其中putty是最出色的一个,支持linux服务器,这点很重要“免费的”.下面就让我们来看一下吧! ...

  8. JAVA学习(七):方法重载与方法重写、thiskeyword和superkeyword

    方法重载与方法重写.thiskeyword和superkeyword 1.方法重载 重载可以使具有同样名称但不同数目和类型參数的类传递给方法. 注: 一是重载方法的參数列表必须与被重载的方法不同,而且 ...

  9. 操作系统学习笔记:I/O输入系统

    计算机两大主要任务:IO操作和计算处理.许多情况下,主要是IO操作,计算处理只是附带的(而操作系统的两大任务是管理物理设备和为应用程序提供一个虚拟机器的抽象).操作系统在IO方面的作用是管理IO操作和 ...

  10. java8--IO(java疯狂讲义3复习笔记)

    产生文件 File file = new File("abc.txt"); if(!file.exists()){ System.out.println(file.exists() ...