在一个具有多服务的应用中,假如由于其中某一个服务出现问题,导致响应速度变慢,或是根本没有响应返回,会导致它的服务消费者由于长时间的等待,消耗尽线程,进而影响到对其他服务的线程调用,进而会转变为整个应用的故障。这也被称之为雪崩效应。

而Hystrix熔断器,正是用来帮助我们解决这种问题的工具。

Hystrix提供了熔断、隔离、fallback、cache、监控等功能,能够在一个或多个服务出现问题的时候保证整个应用依然处于可用状态。

没有做熔断处理的应用,出现问题后:

正常情况:                              A→B→C→D

D服务出现了问题:                              A→B→C×D

从而导致C服务无法获取正确的响应,出现对应的问题:              A→B×C×D

最后导致B服务,甚至A服务都同样出现问题,由服务不可用变为应用不可用:   A×B×C×D

针对于上面的这种情况,在Hystrix中采用了如下的几种方式进行处理。

1.Hystrix请求超时

用hystrix监控请求的响应时间,如果超过我们设置的时间,将会被判定为请求超时,抛出TimeoutException。

(1)引入Maven依赖

    <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.2..RELEASE</version>
</dependency>

(2)在properties中进行配置。

关于参数详解可以参考https://blog.csdn.net/u013889359/article/details/80118884https://blog.csdn.net/tongtong_use/article/details/78611225https://blog.csdn.net/nb7474/article/details/84440822

#超时时间,默认1000,单位ms。
#注意这里配置的default,默认所有的请求服务都被设定为这个值。如果要针对某一个服务,可以将default改为服务名如user,或在请求类中通过注解进行单独配置
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=

(3)在启动类中添加注解@EnableCircuitBreaker

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class RoleServerApplication { public static void main(String[] args) {
SpringApplication.run(RoleServerApplication.class, args);
} }

(4)在需要被Hystrix控制请求时间的方法上添加注解@HystrixCommand。如果方法没有被配置这个注解,请求将不会达到指定时间后抛出超时异常。

    @GetMapping("roles/{id}")
@HystrixCommand
public String getRole(@PathVariable("id") String id) {
System.out.println("接收到请求[/roles/" + id + "]");
return restTemplate.getForObject(rest_url_prefix + "/users/" + id, String.class);
}

如此完成了一个请求的超时配置,假如方法getRole()对/users/{id}请求的时间超过了一秒没有得到相应,那么会抛出如下异常:

2. 对服务分别配置线程池调用

不同的服务配置了不同的线程池,这样可以即使向服务A发送的请求都超时,占满了线程数。但是向服务B发送的请求仍然处于正常状态,不会受到A服务的干扰。

(1)引入MAVEN依赖

    <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.2.7.RELEASE</version>
</dependency>

(2)在properties中进行配置(注意这里配置的都是default,默认适应所有的被@HystrixCommand修饰的方法中的请求,如果需要分别针对不同的服务,替换defalut即可)。

#超时时间,默认1000,单位ms。
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=100000
#线程池核心线程数,最多同时只有2个线程在执行
hystrix.threadpool.default.coreSize=2
#线程池最大队列数,也可以理解为最多只能添加4个请求进来。包括正在执行的请求。
hystrix.threadpool.default.maxQueueSize=4
#线程池最大线程数。最多只能接收2+3=5个线程数。
hystrix.threadpool.default.maximumSize=3
#队列拒绝阈值,即使队列数没有达到maxQueueSize,也会拒绝接收任务
hystrix.threadpool.default.queueSizeRejectionThreshold=6

(3)在启动类中添加注解@EnableCircuitBreaker

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class RoleServerApplication { public static void main(String[] args) {
SpringApplication.run(RoleServerApplication.class, args);
} }

(4)在需要被Hystrix控制请求时间的方法上添加注解@HystrixCommand,同时在注解内填入应急方法的方法名,并定义好应急方法。

    @GetMapping("roles/{id}")
@HystrixCommand(fallbackMethod = "getRoleFallbackMethod")
public String getRole(@PathVariable("id") String id) {
System.out.println(LocalDateTime.now().toString() + "接收到请求[/roles/" + id + "]");
return restTemplate.getForObject(rest_url_prefix + "/users/" + id, String.class);
} public String getRoleFallbackMethod(String id) {
System.out.println(LocalDateTime.now().toString() + "进入fallBackMethod!");
return "进入fallBackMethod";
}

上面的步骤执行完成后,我们再多次调用getRole(String)方法,根据我们上面配置的参数,设置超时时间100秒是为了让请求一直保持存活状态。

假如请求的线程数超过了线程池中允许的最大线程,会抛出线程池拒绝异常,或是进入fallback方法。

3.Hystrix服务熔断

不论是请求超时还是线程池的配置,服务熔断做的更为彻底。

在一定的时间范围内,向A服务发送的请求失败率达到了一个指定的比例,会开启熔断器。熔断器开启后,所有向A服务发起的请求都将不会被发起请求,而是或抛出异常,或调用fallback方法。当熔断器开启达到指定时间后,会重新向A服务发起一次请求,如果请求失败,熔断器继续保持开启状态。如果请求成功,则熔断器关闭。

(1)引入MAVEN依赖

    <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.2..RELEASE</version>
</dependency>

(2)在properties中进行配置(注意这里配置的都是default,默认适应所有的被@HystrixCommand修饰的方法中的请求)。

#一个rolling window内最小的请求数。如果请求数少于该值,则不论如何也不会触发短路。
hystrix.command.default.circuitBreaker.requestVolumeThreshold=
#错误率阈值。如果一个rolling window内的请求错误率超过了该值,则会开启熔断器
hystrix.command.default.circuitBreaker.errorThresholdPercentage=0.5
#触发短路的时间值,单位毫秒。
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=

(3)在启动类中添加注解@EnableCircuitBreaker

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class RoleServerApplication { public static void main(String[] args) {
SpringApplication.run(RoleServerApplication.class, args);
} }

(4)在需要被Hystrix控制请求时间的方法上添加注解@HystrixCommand,同时在注解内填入应急方法的方法名,并定义好应急方法。

    @GetMapping("roles/{id}")
@HystrixCommand(fallbackMethod = "getRoleFallbackMethod")
public String getRole(@PathVariable("id") String id) {
System.out.println(LocalDateTime.now().toString() + "接收到请求[/roles/" + id + "]");
return restTemplate.getForObject(rest_url_prefix + "/users/" + id, String.class);
} public String getRoleFallbackMethod(String id) {
System.out.println(LocalDateTime.now().toString() + "进入fallBackMethod!");
return "进入fallBackMethod";
}

(5)这里我们编写一个服务提供者代码,假如接收到的id中有1,那么会正确返回,如果接收到的id中没有1,那么会休眠100秒,导致请求超时。

    @GetMapping("users/{id}")
public String getUser(@PathVariable("id") String id) {
if (StringUtils.contains(id, "")) {
return "ok";
}
try {
Thread.sleep(*);
} catch (InterruptedException e) {
e.printStackTrace();
}
String user = service.findUser(id);
return user;
}

请求结果:

我们可以先测试id=1的请求,如下图,发现请求正常,此时circuit处于closed状态。

然后我们再发送几条id为其他值的请求,此时发现请求error,circuit已经变成了open状态。这个时候即使我们发送id=1的请求也同样会被进入到fallback方法中。

只有当circuit被开启了指定的sleepWindowInMillisecond数后,再发送id=1的数据,circuit会重新变为close。

hystrix熔断器的更多相关文章

  1. SpringCloud学习(6)——Hystrix熔断器

    分布式系统面临的问题 复杂的分布式体系结构中的应用程序有数十个依赖关系, 每个依赖关系在某些时刻不可避免的失败. 服务雪崩效应 多个微服务调用的时候, 假设微服务A调用微服务B和微服务C, 微服务B和 ...

  2. Spring cloud微服务 Hystrix熔断器学习教程

    以下demo代码:https://github.com/wades2/HystrixtDemo 官网定义:Hystrix是一个延迟容错库.在分布式环境中,许多服务依赖项中的一些不可避免地会失败.Hys ...

  3. Spring Cloud Hystrix 熔断器(五)

    序言 感觉hystrix很精彩,文档讲的也很好,这篇总结到哪里是哪里吧 写Hystrix之前,我们先简单的说说熔断器,和限流,这样你看完之后,就可以很容易理解Hystrix 熔断器 熔断器模式源于Ma ...

  4. Spring-Cloud之Hystrix熔断器-5

    一.在分布式系统中,服务与服务之间的依赖错综复杂,一种不可避免的情况就是某些服务会出现故障,导致依赖于它们的其他服务出现远程调度的线程阻塞 Hystrix是Netflix 公司开源的一个项目,它提供了 ...

  5. springcloud之hystrix熔断器-Finchley.SR2版

    本篇和大家分享的是springcloud-hystrix熔断器,其主要功能是对某模块调用失败做断路和降级,简单点就当某个模块程序出问题了并达到某阈值就限制后面请求,并降级的方式提供一个默认返回数据.最 ...

  6. SpringCloud之初识Hystrix熔断器 ----- 程序的保护机制

    在上一篇的-负载均衡Robbin中,我们简单讲解到负债均衡的算法和策略.负载均衡就是分发请求流量到不同的服务器,以减小服务器的压力和访问效率,但是当负载均衡的某个服务器或是服务挂掉之后,那么程序会出现 ...

  7. SpringCloud无废话入门04:Hystrix熔断器及监控

    1.断路器(Circuit Breaker)模式 在上文中,我们人为停掉了一个provider,在实际的生产环境中,因为意外某个服务down掉,甚至某一层服务down掉也是会是有发生的.一旦发生这种情 ...

  8. Spring Cloud Hystrix——熔断器

    1.雪崩效应在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应.服务雪崩效应是一种因“服务提供者”的不可用导致“服务消费者 ...

  9. SpringCloud-容错处理Hystrix熔断器(五)

    前言:微服务架构应用的特点就是多服务,而服务层之间通过网络进行通信,从而支撑起整个应用系统,所以,各个微服务之间不可避免的存在耦合依赖关系.但任何的服务应用实例都不可能永远的健康或网络不可能永远的都相 ...

随机推荐

  1. 容斥原理——hdu1796

    /* 遇到这种题一般用dfs,枚举起点来做 但是本题如何进行容斥? 比如以x为起点,第一步dfs到y,那么因子有lcm(x,y)的 所有数要被减掉(容斥中偶数是减法) 然后第二步dfs到z,那么因子有 ...

  2. javaweb的几种开发模式

    1.MVC模式基础 1.1.MVC模式简介 MVC是一种架构型模式,它本身并不引入新的功能,只是用来指导我们改善应用程序的架构,使得应用的模型和视图相分离,从而达到更好的开发和维护效率.在MVC模式中 ...

  3. linux 详解

    一.日常使用命令/常用快捷键命令开关机命令        1.shutdown –h now:立刻进行关机 2.shutdown –r now:现在重新启动计算机 3.reboot:现在重新启动计算机 ...

  4. MySQL数据库--创建表,查询

    MySQL创建表: 表(一)Student (学生表): CREATE TABLE `Student` ( `sno` ) DEFAULT NULL, `sname` ) DEFAULT NULL, ...

  5. 关于set的unordered特性

    关于set排序无序的问题,原因是set使用哈希表做内存索引. 详细介绍可见: https://stackoverflow.com/questions/12165200/order-of-unorder ...

  6. Python-流程控制 if判断

    目录 if 判断 语法 单分支结构 双分支结构 多分支结构 for循环 语法 for + break for + continue for + else range函数 for + if 练习 if ...

  7. Django项目:CRM(客户关系管理系统)--61--51PerfectCRM实现CRM客户报名流程学生合同上传照片

    # sales_views.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.db import IntegrityError # 主动 ...

  8. 深入了解组件- -- 动态组件 & 异步组件

    gitHub地址:https://github.com/huangpna/vue_learn/example里面的lesson11 一 在动态组件上使用keep-alive 在这之前我们已经有学习过用 ...

  9. 路由的配置,侧边栏类名与url的结合运用

    var url_array = document.location.pathname.split("/"); s1 = url_array[1]; s2 = url_array[2 ...

  10. MyBatis配置文件(八)--databaseIdProvider数据库厂商标识

    databaseIdProvider元素主要是为了支持不同厂商的数据库,比如有时候我们在公司内部开发使用的数据库都是PG(Postgresql),但是客户要求使用MySql,那就麻烦了是吧?其实在my ...