什么是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 服务熔断和服务降级的更多相关文章

  1. SpringCloud学习之Hystrix请求熔断与服务降级(六)

    我们知道大量请求会阻塞在Tomcat服务器上,影响其它整个服务.在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败.高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险 ...

  2. Spring Cloud实战之初级入门(四)— 利用Hystrix实现服务熔断与服务监控

    目录 1.环境介绍 2.服务监控 2.1 加入依赖 2.2 修改配置文件 2.3 修改启动文件 2.4 监控服务 2.5 小结 3. 利用hystrix实现消费服务熔断 3.1 加入服务熔断 3.2 ...

  3. Hystrix请求熔断与服务降级

    Hystrix请求熔断与服务降级 https://www.cnblogs.com/huangjuncong/p/9026949.html SpringCloud实战-Hystrix请求熔断与服务降级 ...

  4. 服务容错保护断路器Hystrix之六:服务熔断和服务降级

    伴随着微服务架构被宣传得如火如荼,一些概念也被推到了我们面前(管你接受不接受),其实大多数概念以前就有,但很少被提的这么频繁(现在好像不提及都不好意思交流了).想起有人总结的一句话,微服务架构的特点就 ...

  5. SpringCloud实战-Hystrix请求熔断与服务降级

    我们知道大量请求会阻塞在Tomcat服务器上,影响其它整个服务.在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败.高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险 ...

  6. 跟我学SpringCloud | 第五篇:熔断监控Hystrix Dashboard和Turbine

    SpringCloud系列教程 | 第五篇:熔断监控Hystrix Dashboard和Turbine Springboot: 2.1.6.RELEASE SpringCloud: Greenwich ...

  7. Hystrix(服务熔断,服务降级)

    一.Hystrix 1.服务雪崩 多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C有调用其他的微服务,这就是所谓的”扇出”,如扇出的链路上某个微服务的调用响应式过长或者 ...

  8. Hystrix断路器中的服务熔断与服务降级

    一.Hystrix断路器 微服务架构特点就是多服务,多数据源,支撑系统应用.这样导致微服务之间存在依赖关系.如果其中一个服务故障,可能导致系统宕机,这就是所谓的雪崩效应. 1.为什么需要断路器 服务雪 ...

  9. Feign + Hystrix 服务熔断和服务降级

    本机IP为  192.168.1.102 1.    新建 Maven 项目   feign 2.   pom.xml <project xmlns="http://maven.apa ...

随机推荐

  1. 十分钟搞懂Elasticsearch数字搜索原理

    更多精彩内容请看我的个人博客或者扫描二维码,关注微信公众号:佛西先森 前言 Elasticsearch诞生的本意是为了解决文本搜索太慢的问题,ES会默认将所有的输入内容当作字符串来理解,对于字段类型是 ...

  2. javascript-数组简单的认识

    一起组团(什么是数组) 我们知道变量用来存储数据,一个变量只能存储一个内容.假设你想存储10个人的姓名或者存储20个人的数学成绩,就需要10个或20个变量来存储,如果需要存储更多数据,那就会变的更麻烦 ...

  3. 转:handler.post 为什么要将thread对象post到handler中执行呢?

    转载网址:http://blog.csdn.net/fei0724/article/details/8664462在Android中使用Handler和Thread线程执行后台操作 对于线程的控制,我 ...

  4. thinkphp5.0 模型的应用

    <?php namespace app\admin\controller; use app\common\controller\BaseController; use think\Db;//数据 ...

  5. ajaxReturn案例

    请查看:http://www.cnblogs.com/bushe/p/4625097.html 不用自己写json格式啦,直接拿这个用就可以啦

  6. LeetCode7-ReverseInteger

    LeetCode7-ReverseInteger LeetCodeeasyOverflow 题目 题目所在链接为 LeetCode-7:ReverseInteger 题目描述 给出一个32位的有符号整 ...

  7. PIL库的学习总结及生成GIF

    一.PIL库的概述 PIL(Python Image Library)库是Python语言的第三方库,需要通过pip工具安装. 打开cmd,输入 pip install pillow PIL库支持图像 ...

  8. 《图解 HTTP》 摘要一

    学习过程对书本的内容的摘要以及总结,逐步完善,带有个人理解成分. Web 及网络基础 使用 HTTP 协议访问 Web 客户端:通过获取请求获取服务资源的 Web 浏览器等 HTTP 全称:Htype ...

  9. MongoDB学习(四):通过Java使用MongoDB

    环境配置 在Java项目中使用MongoDB,需要在项目中引入mongo.jar这个包.下载地址:下载 请尽量下载较新的版本,本文用的是2.10.1. 连接MongoDB public synchro ...

  10. memcached 原子性操作 CAS模式

    2019独角兽企业重金招聘Python工程师标准>>> 应用场景分析: 如原来MEMCACHED中的KES的内容为A,客户端C1和客户端C2都把A取了出来,C1往准备往其中加B,C2 ...