SpringCloud Netflix (五) : Hystrix 服务熔断和服务降级
什么是Hystrix
在分布式环境中,许多服务依赖项中的一些服务依赖不可避免地会失败。Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助您控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、防止服务之间的级联故障以及提供回退选项来实现这一点,所有这些都提高了系统的总体弹性。
( 级联故障 )

Hystrix可以做什么
延迟和容错
防止级联故障。回退和优雅的降级。快速恢复失败。
带断路器的线程和信号量隔离。
实时操作
实时监控和配置更改。当服务和属性变更在集群中传播时,立即生效。
保持警觉,做出决定,影响变化,并在几秒钟内看到结果。
并发性
并行执行。支持并发的请求缓存。通过请求折叠自动批处理。

服务熔断和服务降级
服务雪崩
服务熔断和服务降级是解决服务雪崩的手段之一,所以在了解服务熔断和服务降级前,需要先明白什么是服务雪崩。如下图所示,因评论服务的失败,导致整个服务链条的失败,即一个服务失败,导致整条链路的服务都失败的情形,我们称之为服务雪崩。

服务熔断
如上图所示,如果当评论服务不可用或响应过慢时,常理来说,应该等到评论服务恢复可用再来调用,可事实上是,后续每个评论服务请求,还是会等待评论服务响应,这可能会消耗商品详情服务的宝贵资源,如线程,导致资源耗尽,从而使商品详情服务无法处理其他请求。而服务熔断就是解决这个问题的。
当下游的服务因为某种原因突然变得不可用或响应过慢,上游服务为了保证自己整体服务的可用性,不再继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。需要说明的是熔断其实是一个框架级的处理,而基本上业内用的是断路器模式;

注意,这时商品详情服务还是会因为评论服务请求失败报Hystrix circuit short-circuited and is OPEN异常而不可用,单纯的服务熔断只是避免重复调用不可用的评论服务而已,不要把熔断和熔断降级归为一起,后面实现可以看一些区别。
断路器背后的基本思想非常简单。在断路器对象中包装受保护的函数调用,该对象监视故障。一旦故障达到某一阈值,断路器就会跳闸,所有对断路器的进一步呼叫都会返回错误,而根本不进行受保护的呼叫。通常,如果断路器跳闸,您还需要某种监视器警报。 ---Martin Fowler
那断路器什么时候打开和关闭呢?
以Hystrix的断路器为例,每当20个请求中,有50%失败时,断路器就会打开,此时再调用此服务,将会直接返回失败,不再调远程服务。直到5s钟之后,会跳到半开模式,放一次请求进来,重新检测服务是否恢复正常,判断是否把断路器关闭,或者继续打开。

服务降级
服务熔断虽然避免了许多无用的调用,但是商品详情服务还是会因为相比不太重要的评论服务失败而不可用,那是不合理的。那能不能在评论服务请求失败时,不影响商品详情服务的正常使用呢?这时候就需要使用服务降级了。(注意,服务降级有很多种降级方式!如开关降级、限流降级、熔断降级! 熔断降级是采用了服务熔断的降级方式,可以说熔断降级是服务降级方式的一种,不要把熔断降级想为单单是熔断)
降级有两种场景:
当下游的服务因为某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放出服务器资源,增加响应速度。(开关降级)
当下游的服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速返回给用户。(熔断降级)

Hyrtix实现服务熔断和服务降级
创建hystrix-details、hystrix-comment、hystrix-goods、hystrix-price服务模拟上图4个服务,并4个服务注册到注册中心。
添加Hystrix依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.7.RELEASE<version>
</dependency>
实现服务熔断
在hystrix-details的启动类上添加注解@EnableCircuitBreaker,允许创建断路器
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableCircuitBreaker
public class HystrixDetails {
public static void main(String[] args) {
SpringApplication.run(HystrixDetails.class, args);
}
}
在需要熔断功能的方法上添加注解@HystrixCommand,将方法添加进断路器监控中
@GetMapping("/details")
@HystrixCommand
public String details() throws RuntimeException, InterruptedException{
return "goods:"+goodsFeignClient.goods()+
" price:"+priceFeignClient.price()+
" comment:"+commentFeignClient.comment();
}
在hystrix-comment被调用的方法里添一行错误代码或线程睡眠,模拟服务不可用或响应过慢,启动各个服务,访问 hystrix-details里details()方法地址localhost:8080/details,快速刷新20次以上,触发断路器打开。
之后查看控制台,会发现当断路器打开后,hystrix-comment报错时间异常间隔为5秒 (hystrix休眠窗时间) ,hystrix-details报错异常从feign.FeignException: status 500 reading CommentFeignClient#comment(); content: 变成java.lang.RuntimeException: Hystrix circuit short-circuited and is OPEN,说明在断路器打开的时间内,hystrix-details对hystrix-comment请求并没有进入到hystrix-comment服务中,而是被断路器拦截了,服务熔断实现成功。一般不会单独使用熔断,而会使用熔断+降级的熔断降级。
实现服务降级(熔断降级)
在之前代码中的注解@HystrixCommand里添加 fallbackMethod = "detailsFallback" 并创建detailsFallback方法。
@GetMapping("/details")
@HystrixCommand(fallbackMethod = "detailsFallback")
public String details() throws RuntimeException, InterruptedException{
return "goods:"+goodsFeignClient.goods()+
" price:"+priceFeignClient.price()+
" comment:"+commentFeignClient.comment();
}
public String detailsFallback(){
return "goods:"+goodsFeignClient.goods()+
" price:"+priceFeignClient.price()+
" comment:error";
}
这时候访问localhost:8080/details,hystrix-detail服务请求hystrix-comment服务失败后会触发降级,调用退步方法fallback() ,hystrix-detail服务不会报异常,页面状态200正常。在这里的fallback是降级机制的一种,所以只要在@HystrixCommand 注解里加上fallbackMethod属性值,就不单单是熔断了,而是熔断降级。
FallbackFactory
当我们实际使用服务降级时,不应该使用上面这种方式。当一个访问中要调用多个服务时,fallback的回退方法就会非常臃肿,后期维护困难,代码耦合度高,且一个方法一个fallback也增加了代码量。所以我们应该面向服务,把每个服务的fallback包装起来,在调用服务的接口上实现fallback,FallbackFactory就是hystrix提供给我们来实现这一举措的。
1.创建一个CommentFallbackFactory类实现FallbackFactory<T>接口
@Component
public class CommentFallbackFactory implements FallbackFactory<CommentFeignClient> {
@Override
public CommentFeignClient create(Throwable throwable) {
return new CommentFeignClient() {
@Override
public String comment() {
return "error";
}
};
}
}
2.在调用hystrix-comment服务的feign接口的@FeignClient里加上
fallbackFactory = CommentFallbackFactory.class
@Component //必须填加,否则应用会扫描不到
@FeignClient(value = "HYSTRIX-COMMENT", fallbackFactory = CommentFallbackFactory.class)
public interface CommentFeignClient {
@GetMapping("/")
String comment();
}
3.在配置里开启feign的hystrix
feign允许开启hystrix后, 会自动把所有服务的feign接口下的方法加入到断路器监控中
feign:
hystrix:
enabled: true
HystrixCommandProperties
我们可以在配置里修改 HystrixCommandProperties 类(在com.netflix.hystrix包下)里的变量,包括修改断路器的休眠窗时间circuitBreakerSleepWindowInMilliseconds、修改响应超时时间executionTimeoutInMilliseconds等
hystrix:
command:
default: #default全局有效,service id指定应用有效
#配置的属性名在HystrixCommandProperties类的构造方法下可以找到
execution:
timeout:
enabled: true #是否开启超时熔断
circuitBreaker:
sleepWindowInMilliseconds: 10000 #把断路器的休眠窗时间设为10秒,默认为5秒
Hystrix仪表盘
Hystrix的主要好处之一是它收集的有关每个HystrixCommand的一组度量。Hystrix仪表板以有效的方式显示每个断路器的运行状况。
1.新建module,springcloud-consumer-hystrix-dashboard
添加 hystrix-dashboard 相关依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
添加配置
@SpringBootApplication
//开启仪表盘
@EnableHystrixDashboard
public class HystrixDashboard { public static void main(String[] args) {
SpringApplication.run(HystrixDashboard.class,args);
} }
2.在服务提供者
添加监控依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在启动类添加ServletRegistrationBean
@SpringBootApplication
@MapperScan("com.example.springcloud.mapper")
@EnableDiscoveryClient
public class Provider_8002 { public static void main(String[] args) {
SpringApplication.run(Provider_8002.class,args);
} @Bean
public ServletRegistrationBean servletRegistrationBean(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
registrationBean.addUrlMappings("/actuator/hystrix.stream");
return registrationBean;
}
}
3.测试访问
访问 localhost:9001/hystrix

输入要监控的微服务 http://localhost:8002/actuator/hystrix.stream

SpringCloud Netflix (五) : Hystrix 服务熔断和服务降级的更多相关文章
- SpringCloud学习之Hystrix请求熔断与服务降级(六)
我们知道大量请求会阻塞在Tomcat服务器上,影响其它整个服务.在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败.高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险 ...
- Spring Cloud实战之初级入门(四)— 利用Hystrix实现服务熔断与服务监控
目录 1.环境介绍 2.服务监控 2.1 加入依赖 2.2 修改配置文件 2.3 修改启动文件 2.4 监控服务 2.5 小结 3. 利用hystrix实现消费服务熔断 3.1 加入服务熔断 3.2 ...
- Hystrix请求熔断与服务降级
Hystrix请求熔断与服务降级 https://www.cnblogs.com/huangjuncong/p/9026949.html SpringCloud实战-Hystrix请求熔断与服务降级 ...
- 服务容错保护断路器Hystrix之六:服务熔断和服务降级
伴随着微服务架构被宣传得如火如荼,一些概念也被推到了我们面前(管你接受不接受),其实大多数概念以前就有,但很少被提的这么频繁(现在好像不提及都不好意思交流了).想起有人总结的一句话,微服务架构的特点就 ...
- SpringCloud实战-Hystrix请求熔断与服务降级
我们知道大量请求会阻塞在Tomcat服务器上,影响其它整个服务.在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败.高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险 ...
- 跟我学SpringCloud | 第五篇:熔断监控Hystrix Dashboard和Turbine
SpringCloud系列教程 | 第五篇:熔断监控Hystrix Dashboard和Turbine Springboot: 2.1.6.RELEASE SpringCloud: Greenwich ...
- Hystrix(服务熔断,服务降级)
一.Hystrix 1.服务雪崩 多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C有调用其他的微服务,这就是所谓的”扇出”,如扇出的链路上某个微服务的调用响应式过长或者 ...
- Hystrix断路器中的服务熔断与服务降级
一.Hystrix断路器 微服务架构特点就是多服务,多数据源,支撑系统应用.这样导致微服务之间存在依赖关系.如果其中一个服务故障,可能导致系统宕机,这就是所谓的雪崩效应. 1.为什么需要断路器 服务雪 ...
- Feign + Hystrix 服务熔断和服务降级
本机IP为 192.168.1.102 1. 新建 Maven 项目 feign 2. pom.xml <project xmlns="http://maven.apa ...
随机推荐
- Java面试系列第2篇-Object类中的方法
Java的Object是所有引用类型的父类,定义的方法按照用途可以分为以下几种: (1)构造函数 (2)hashCode() 和 equals() 函数用来判断对象是否相同 (3)wait().wai ...
- pytorch中的前项计算和反向传播
前项计算1 import torch # (3*(x+2)^2)/4 #grad_fn 保留计算的过程 x = torch.ones([2,2],requires_grad=True) print(x ...
- 一种特殊的生成器函数-Generator函数
本节的内容,是建立在iterator遍历器知识的基础上.所以希望还没有看上一节的内容的话,最好还是看一看,当然你如果熟悉iterator就没有那个必要了. 既然你都看到这里来了,就咱们就接着往下讲.. ...
- 基于centos7搭建kvm
其他的和安装一般的系统没有差别 安装完成后. 1]使用ping www.baidu.com 2]修改静态ip,也可以不修改 3]下载brctlyum -y install bridge-utils 4 ...
- [开发笔记]-unix时间戳、GMT时间与datetime类型时间之前的转换
前段时间项目中涉及到了MySql和MsSql数据类型之间的转换,最近又在研究新浪微博的API,涉及到了带有时区的GMT时间类型的转换,所以,特记录于此,以备日后查询. 一:UNIX时间戳与dateti ...
- 第 43 章 Baidu Map
43.1. BMap.Circle var point = new BMap.Point(22.111, 114.111); var styleCircleF = { strokeColor:&quo ...
- 在sun jdk 8镜像基础上构建maven 3的docker镜像
2019独角兽企业重金招聘Python工程师标准>>> 在https://my.oschina.net/ytqvip/blog/1595054文章的sun jdk 8镜像基础上构建m ...
- STL训练 HDU - 1716 Ray又对数字的列产生了兴趣:
HDU - 1716 Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数. Input 每组数据占一行,代表四张卡片上的数字(0&l ...
- andorid jar/库源码解析之错误提示
目录:andorid jar/库源码解析 错误: 错误1: Error: Static interface methods are only supported starting with Andro ...
- Python词云生成
一.目的 1. 熟悉jieba库和wordcloud库的使用方法: 2. 熟悉文本词频统计和词云生成的基本方法. 二.内容 1. 从网上自行下载一个长篇英文小说,统计并输出该小说中词频最大的TOP 2 ...