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 ...
随机推荐
- 进阶 Linux基本命令-1
vmware三种网络模式1,桥接虚拟机直接连接外网,局域网.宿主机电脑不提供路由. 2,NAT网络地址转换,家庭网 3,host only 只能和宿主电脑打交道 Linux命令形式 命令 +[参数]+ ...
- 微信小程序填坑---小程序支付
因为公司刚刚重新做了网站,所以也吧公众号和小程序提上了日程,在公众号里面没有什么问题,直接按照官方文档进行代码编写.调试,然后就解决了公众号内支付的问题. 因为小程序提供了<webview> ...
- IDE使用GIT控制项目版本
IDEA本身继承GIT开发插件.只需要安装windows git客户端即可使用. check in project 检入项目 将新创建的项目上传到服务器. 对于git来说,空的目录不会上传到远程仓库. ...
- java学习(第五篇)包装类
一.Integer package com.test01; public class IntegerTest01 { public static void main(String[] args) { ...
- ubuntu server 18.04 网络配置
从17.10开始放弃在/etc/network/interfaces里固定IP的配置 配置文件是:/etc/netplan/50-cloud-init.yaml .用缩进来表示层级关系 冒号之后要有个 ...
- 日志分析工具ELK(四)
Logstash收集TCP日志 #Input plugins TCP插件 所需的配置选项 tcp { port =>... } [root@linux-node1 ~]# cat tcp.con ...
- springboot中Redis的Lettuce客户端和jedis客户端
1.引入客户端依赖 <!--jedis客户端依赖--> <dependency> <groupId>redis.clients</groupId> &l ...
- 【Linux常见命令】tar命令
[独立命令,只能用其中一个,和别的命令连用]这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个. -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末 ...
- python 多进程处理 multiprocessing模块
前提: 有时候一个用一个进程处理一个列表中的每个元素(每个元素要传递到一个函数中进行处理),这个时候就要用多进程处理 1 现场案例: 我有一个[ip1,ip2,ip3,.......]这样的列表,我要 ...
- EntityFramework 迁移遇到的问题
2019独角兽企业重金招聘Python工程师标准>>> 添加迁移add-migration migrationname 更新数据Update-Database EntityFrame ...