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

而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. 数论整除——cf1059D

    用map是卡着过去的..题解用vector+离散化后常数小了十倍.. 总之就是把所有模数给保存下来然后离散化,再去匹配一下即可,最后有个细节 自己的 #include<bits/stdc++.h ...

  2. python用reduce和map把字符串转为数字的方法

    python用reduce和map把字符串转为数字的方法 最近在复习高阶函数的时候,有一道题想了半天解不出来.于是上午搜索资料,看了下别人的解法,发现学习编程,思维真的很重要.下面这篇文章就来给大家介 ...

  3. dp练习集

    动态规划(DP) // 以下题目来自牛客网 删括号 f[i][j][k] 表示序列s的前i个匹配序列t的前j个,序列s删除部分左括号与右括号数量差为k的情况是否可行 答案为 f[sl][tl][0] ...

  4. 左神算法书籍《程序员代码面试指南》——1_01设计一个有getMin功能的栈

    [题目] 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作. [要求] 1.pop.push.getMin操作的时间复杂度都是O(1).2.设计的栈类型可以使用现成的栈结构. ...

  5. Apollo Lake设计缺陷,避免使用它们

    很多经验告诉我们,在不大幅加电压超频的情况下,CPU很少会用坏.多数情况下电脑退役都是主板或其他部件故障,或是性能严重落后而不得不淘汰.但是如果CPU在制造阶段就存有缺陷的话,情况就不是这样了. 英特 ...

  6. Django之模板语言(三)------>自定义filter

    1.自定义filter: 1.在app01下面新建一个templatetags的python package包. 如果没有app01的话,可以通过命令行在manage中进行创建:python mana ...

  7. 解决Navicat 报错:1130-host is not allowed MySQL不允许从远程访问的方法

    ERROR 1130: Host '192.168.1.3' is not allowed to connect to thisMySQL server 解决方法: 1. 改表法.可能是你的帐号不允许 ...

  8. JS的同步和异步加载

    引言 JS的“加载”不能理解为下载,它是分为两个部分:下载,执行.默认的JS加载是同步的,因为浏览器需要一个稳定的DOM结构,而执行JS时可能会对DOM造成改变,所以在执行JS时一定会阻塞HTML的渲 ...

  9. ArcGIS Data Interoperability 的使用(1)

    今天在用OneMap的时候,发现OneMap中注册过后的WFS服务无法在skyline中加载,于是想知道OneMap注册后的WFS服务与server中的原生态WFS服务有啥区别.首先想到是否能在Arc ...

  10. C# 窗体内容显示不全

    在T430上安装skyline的CS版时候,发现登陆窗口显示的内容不全,第二个缓冲的窗口也显示不全.设置了下面的参数后就可以了.