一、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. Spring中实现自定义事件

    原理: 通过扩展ApplicationEvent,创建一个事件类CustomEvent.这个类必须定义一个默认的构造函数,它应该从ApplicationEvent类中继承的构造函数. 一旦定义事件类, ...

  2. 系统性能不够原因可能是cpu不够,内存不够等等

    1.Linux系统可以通过top命令查看系统的CPU.内存.运行时间.交换分区.执行的线程等信息. 通过top命令可以有效的发现系统的缺陷出在哪里.是内存不够.CPU处理能力不够.IO读写过高. 2. ...

  3. 关键字检索高亮标出-javasript/jQuery代码实现

    原文:http://www.open-open.com/code/view/1454504432089 此方法传入2个参数,一个是被检索内容所在的表单或者HTML元素的ID,另一为关键字,多个关键字的 ...

  4. 9.Laravel5学习笔记:在laravel中注冊自己的服务到容器中

    问题描写叙述 或许标题写的不够清楚.实际情况是,在我使用laravel的过程中.须要将自己的一个类,通过服务提供者注冊到IOC容器中,可是在实际操作过程中.出现了下面错误: Unresolvable ...

  5. 到底该不该使用存储过程 MySQL查询性能优化一则

    到底该不该使用存储过程   看到<阿里巴巴java编码规范>有这样一条 关于这条规范,我说说我个人的看法 用不用存储过程要视所使用的数据库和业务场景而定的,不能因为阿里巴巴的技术牛逼,就视 ...

  6. hdu1576 mod 运算的逆元

    Problem Description 要求(A/B)%9973,但因为A非常大,我们仅仅给出n(n=A%9973)(我们给定的A必能被B整除.且gcd(B,9973) = 1).   Input 数 ...

  7. 6 使用Ionic开发天气应用

    简介:本节课我们会制作一款天气应用,这款应用允许用户查看当前的天气情况.天气预报以及地点收藏,在模态框内显示日出和日落的数据,使用分页滚动面板显示天气信息,使用侧滑菜单实现导航. 6.1 项目配置 环 ...

  8. android 之EditText输入检測

    近期开发一个功能的时候发生一个故事,其情节例如以下: 功能事实上不复杂,当中须要一个EditText来获取用户输入的信息.于是,我做了一个Dialog来显示我的输入界面(代码例如以下): mAlert ...

  9. 正则表达式ab?c匹配的字符串是?(B)

    A:abcd B:abc C:abcbc D:aEbc

  10. create database 默认utf-8

    CREATE DATABASE IF NOT EXISTS dbname DEFAULT CHARSET utf8 COLLATE utf8_general_ci; 这是sql语句 CREATE TA ...