Hystrix介绍

相对于单一系统,分布式系统更容易遇到故障,所以我们一般通过构建冗余,使用集群和负载均衡来保证系统的弹性和高可用。当然,这种方式只解决了一部分问题,当服务崩溃时,我们很容易检测到,因此可以分流到集群中其他的服务中。但是,如果整个服务集群运行缓慢,不仅难以检测原因,而且还会触发连锁效应,从而影响整个应用程序生态系统,如果没有保护措施,一个性能不佳的服务可以迅速拖跨整个应用程序。原因如下:

(1)服务的降级一般以某个问题开始,最终突然爆发,并形成不可逆转的势头。

(2)对于远程调用该服务的客户端服务,这个调用一般是同步的,并且会一直等待(如果没有设定超时)

(3)客户端服务遇到这种调用,通常设计为系统异常,而不是部分降级。

我们可以使用Netflix的Hystrix实现客户端弹性模式,当服务崩溃时我们可以让客户端快速失败,免于崩溃,从而不继续占用如数据库连接,线程池之类的宝贵资源,并且防止故障向上游的级联传播(stop cascading failure)。一般有4种客户端弹性模式:

(1)客户端负载均衡(client load balance)模式 - 在Spring Cloud中,Netflix Eureka及Ribbon实现了负载均衡,在服务发现(Eureka)一章中已经讲过,不再赘述

(2)断路器(circuit breaker)模式 - Netflix Hystrix

(3)后备(fallback)模式 - Netflix Hystrix

(4)舱壁(bulkhead)模式 - Netflix Hystrix

Hystrix策略

断路器(circuit breaker)模式

Hystrix默认的服务调用超时时间是是1s(execution.isolation.thread.timeoutInMilliseconds, default = 1000),当Hystrix遇到服务错误时,它将开始一个10s的窗口(计时器)(metrics.rollingStats.timeInMilliseconds, default = 10000),用于检查服务调用次数和故障百分比, 如果窗口期间没有达到最小调用次数20次(circuitBreaker.requestVolumeThreshold, default = 20),那么即使有几个(甚至全部)调用失败,Hystrix也不会采取行动(the circuit will not trip)。如果窗口期间达到最小调用次数20次,则要看故障百分比(circuitBreaker.errorThresholdPercentage, default = 50),如果故障百分比未超过50%,且10s的窗口已经过去,则Hystrix将重置断路器的统计信息,进入下一个10s,如果百分比超过50%的阈值,Hystrix将触发断路器,使将来几乎所有调用都失败(会让部分调用来进行测试,以检查服务是否恢复)。如果触发断路器,断路器跳闸后,将进入一个新的的5s窗口(circuitBreaker.sleepWindowInMilliseconds, default = 5000),即每隔5s调用一次这个“坏”服务,如果失败则HHystrix继续保持断开,并进入下一个5s的尝试。如果成功,则Hystrix将重置断路器的统计信息并恢复调用。

隔离策略(execution.isolation.strategy, default = THREAD):分为THREAD和SEMAPHORE。THREAD指在单独的线程上执行,并发请求受线程池中的线程数限制。SEMAPHORE指在调用线程上执行,并发请求量受信号量计数限制。在默认情况下,推荐HystrixCommands使用THREAD隔离策略,HystrixObservableCommand使用SEMAPHORE隔离策略。只有在高并发(单个实例每秒达到几百个调用)的调用时,才需要修改HystrixCommands的隔离策略为SEMAPHORE。

滑动窗口及桶(bucket)(metrics.rollingStats.numBuckets, default = 10):Hystrix的统计器是由滑动窗口(10s)来实现的,bucket是Hystrix统计滑动窗口数据时的最小单位。默认是10,即每滑过窗口的1/10就统计一次数据。

后备(fallback)模式

fallbackMethod属性在当前类中定义了一个方法,如果Hystrix执行失败,就执行该方法

舱壁(bulkhead)模式

在不使用舱壁模式的情况下,Hystrix默认共享同一个线程池来对各个服务执行调用的,而这些服务调用可能是各不相同,比如REST服务,数据库调用等。当某个服务存在大量请求时,Hystrix线程池中的线程可能会被耗尽,因为一个服务会占据默认线程池中的所有线程。而舱壁模式则是为一个微服务中不同的调用创建舱壁,即单独的线程池,池互不影响。我们使用threadPoolKey来定义一个线程池的名字,使用threadPoolProperties来配置属性,其中,coreSize定义线程池中线程的最大数量,maxQueueSize定义排队进入线程池的队列的大小。

[注] 上面标颜色的参数会在下面有具体的使用方式。

使用Hystrix

首先,在一个客户端服务中,在pom.xml中添加依赖spring-cloud-starter-netflix-hystrix。

<!-- Spring cloud starter: netflix-hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

其次,在启动类Application中加入@EnableCircuitBreaker注解。

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

上面3种模式可以如下配置:

    @Autowired
private LoadBalancerClient loadBalancer; @Autowired
private OAuth2RestTemplate restTemplate; //@formatter:off
@HystrixCommand(
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000"),
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "10000"),
@HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "10")
}, // 断路器模式
fallbackMethod = "callFallbackMethod1", // 后备模式
threadPoolKey = "findAllPoolKey",
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "10"),
@HystrixProperty(name = "maxQueueSize", value = "-1")
} // 舱壁模式
)
//@formatter:on
public String getSqlInfo(String env, String db, String name) { ServiceInstance instance = loadBalancer.choose("app-db");
String path = String.format("http://%s:%s/app-db/structure-search/app/MORT/env/%s/db/%s/name/%s",
instance.getHost(), instance.getPort(), env, db, name);
logger.info(path); ResponseEntity<String> response = restTemplate.exchange(path, HttpMethod.GET, null, String.class);
String body = response.getBody();
logger.info("The Response body is: " + body); return body;
} private String callFallbackMethod1(String env, String db, String name) {
return "Result is NULL";
}

我们也可以在类级别和整个应用程序级别设置这些参数。

在类级别是这样设置的:

@DefaultProperties(commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000") })
public class CallService {
}

在production环境中,我们有时候会需要调整Hystrix数据,这种情况下推荐将配置外部化到Spring Cloud Config中,这样就无须再修改代码,编译和部署:

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 

Spring Cloud(4):断路器(Hystrix)的更多相关文章

  1. Spring Cloud入门教程-Hystrix断路器实现容错和降级

    简介 Spring cloud提供了Hystrix容错库用以在服务不可用时,对配置了断路器的方法实行降级策略,临时调用备用方法.这篇文章将创建一个产品微服务,注册到eureka服务注册中心,然后我们使 ...

  2. Spring Cloud 入门 之 Hystrix 篇(四)

    原文地址:Spring Cloud 入门 之 Hystrix 篇(四) 博客地址:http://www.extlight.com 一.前言 在微服务应用中,服务存在一定的依赖关系,如果某个目标服务调用 ...

  3. Spring Cloud(Dalston.SR5)--Hystrix 断路器-缓存

    在 Spring Cloud 中可以使用注解的方式来支持 Hystrix 的缓存,缓存与合并请求功能需要先初始化请求上下文才能实现,因此,必须实现 javax.servlet.Filter 用于创建和 ...

  4. Spring Cloud(Dalston.SR5)--Hystrix 断路器-合并请求

    在 Spring Cloud 中可以使用注解的方式来支持 Hystrix 的合并请求,缓存与合并请求功能需要先初始化请求上下文才能实现,因此,必须实现 javax.servlet.Filter 用于创 ...

  5. Spring Cloud(Dalston.SR5)--Hystrix 断路器

    Spring Cloud 对 Hystrix 进行了封装,使用 Hystrix 是通过 @HystrixCommand 注解来使用的,被 @HystrixCommand 注解标注的方法,会使用 Asp ...

  6. Spring Cloud Feign 整合 Hystrix

    在前面随笔Spring Cloud 之 Feign的feign工程基础上进行改造 1.pom.xml依赖不变 2.application.yml文件添加feign.hystrix.enabled=tr ...

  7. Spring Cloud Ribbon 整合 Hystrix

    在前面随笔 Spring Cloud 之 Ribbon 的ribbon工程基础上进行改造 1.pom.xml 加入依赖 <dependency> <groupId>org.sp ...

  8. 架构师入门:Spring Cloud系列,Hystrix与Eureka的整合

    和Ribbon等组件一样,在项目中,Hystrix一般不会单独出现,而是会和Eureka等组件配套出现.在Hystrix和Eureka整合后的框架里,一般会用到Hystrix的断路器以及合并请求等特性 ...

  9. spring cloud(断路器——初学四)

    在分布式架构中,当某个服务单元发生故障后,能通过断路器的故障监控,向调用方返回一个错误响应,而不是长时间的等待. Netflix Hystrix 在Spring Cloud中使用了Hystrix 来实 ...

  10. spring cloud 学习(4) - hystrix 服务熔断处理

    hystrix 是一个专用于服务熔断处理的开源项目,当依赖的服务方出现故障不可用时,hystrix有一个所谓的断路器,一但打开,就会直接拦截掉对故障服务的调用,从而防止故障进一步扩大(类似中电路中的跳 ...

随机推荐

  1. 牛客练习赛53 E 老瞎眼 pk 小鲜肉 (线段树,思维)

    链接:https://ac.nowcoder.com/acm/contest/1114/E来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 524288K,其他语言1048 ...

  2. FreeIPA ACI (Access Control Instructions) 访问控制说明

    目录 FreeIPA ACI (Access Control Instructions) 访问控制说明 一.ACI 位置 二.ACI 结构 三.ACI 局限性 四.复制拓扑中的ACI 五.操作ACI ...

  3. Prim算法和Kruskal算法介绍

    一.Prim算法 普利姆(Prim)算法适用于求解无向图中的最小生成树(Minimum Cost Spanning Tree).下面是Prim算法构造最小生成树的过程图解.              ...

  4. spark数据倾斜处理

    spark数据倾斜处理 危害: 当出现数据倾斜时,小量任务耗时远高于其它任务,从而使得整体耗时过大,未能充分发挥分布式系统的并行计算优势. 当发生数据倾斜时,部分任务处理的数据量过大,可能造成内存不足 ...

  5. BZOJ 1036 [ZJOI2008]树的统计Count 动态维护树上求和与求最大值 LCT板题

    模板,也可以用树链剖分+线段树做O(nlog2)O(nlog^2)O(nlog2) 用LCT做O(nlog)O(nlog)O(nlog)在乘上一个大于30的常数-然后LCT比树剖慢一倍- CODE # ...

  6. MySQL索引-B+树(看完你就明白了)

    索引是一种数据结构,用于帮助我们在大量数据中快速定位到我们想要查找的数据.索引最形象的比喻就是图书的目录了.注意这里的大量,数据量大了索引才显得有意义,如果我想要在 [1,2,3,4] 中找到 4 这 ...

  7. HDU 6071 - Lazy Running | 2017 Multi-University Training Contest 4

    /* HDU 6071 - Lazy Running [ 建模,最短路 ] | 2017 Multi-University Training Contest 4 题意: 四个点的环,给定相邻两点距离, ...

  8. MySQL基础练习01--牛客网

    目录 1 查找最晚入职员工的信息 2 查找入职第三晚的员工信息 3 查找当前薪水详情及部门编号 4 查找所有员工入职时的薪水情况 5 查找已分配员工姓名 6 查找员工姓名 7 查找涨薪找过15次的员工 ...

  9. Web大文件分片上传

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 先说下要求: PC端全平台支持,要求支持Windows,Mac,Linux 支持所 ...

  10. 小米oj 反向位整数(简单位运算)

     反向位整数 序号:#30难度:一般时间限制:1000ms内存限制:10M 描述 输入32位无符号整数,输出它的反向位. 例,输入4626149(以二进制表示为00000000010001101001 ...