SpringCloud H版 Hystrix 介绍及服务降级讲解
Posted 小毕超
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud H版 Hystrix 介绍及服务降级讲解相关的知识,希望对你有一定的参考价值。
一、Hystrix
前面我们讲解了OpenFeign的使用和注意点,再上节中我们提到了服务降级,服务降级也是一种服务保护的策略,今天我们来讲解下Hystrix 服务保护工具,虽然官方已经声明Hystrix 已经不再更新,但Hystrix 的理念还是值得学习和研究的,了解了hystrix 也可以更好的学习后面的alibab cloud 的Sentinel 框架。
上篇博客地址:https://blog.csdn.net/qq_43692950/article/details/121993565
目前面临的问题
目前分布式系统面临的问题,复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。
多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,这就是所谓的“雪崩效应”。
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。
所以,通常当你发现一个模块下的某个实例失败后,这时候这个模块依然还会接收流量,然后这个有问题的模块还调用了其他的模块,这样就会发生级联故障,或者叫雪崩。
Hystrix的出现
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
Hystrix 的工作流程
二、Hystrix 的整合
一般Hystrix 用在消费者端,也可以用在提供者端,我们主要在消费者端进行演示。
首先引入Hystrix 的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
主启动类中添加 @EnableHystrix 注解
@SpringBootApplication
@EnableHystrix
public class HystrixApplication
public static void main(String[] args)
SpringApplication.run(HystrixApplication.class, args);
三、Hystrix 实现服务降级
上面已经引入了Hystrix 的依赖,我们先来体验下服务的降级,编写测试接口:
@RestController
@RequestMapping("/fallback")
public class TestFallBackController
@HystrixCommand(fallbackMethod = "fallback")
@GetMapping("/getTest")
public ResponseTemplate getTest() throws InterruptedException
int a = 1 / 0;
return ResSuccessTemplate.builder().build();
public ResponseTemplate fallback()
return ResFailTemplate.builder().message("服务降级!").build();
启动服务,调用测试接口http://localhost:8080/fallback/getTest
现在就已经体验了服务降级的效果了,一般服务降级还有一种场景就是接口调用超时,超时的降级,需要我们配置超时时间等,如果不配置默认1s超时,主要做如下改变:
@RestController
@RequestMapping("/fallback")
public class TestFallBackController
@HystrixCommand(fallbackMethod = "fallback")
@GetMapping("/getTest")
public ResponseTemplate getTest() throws InterruptedException
int a = 1 / 0;
return ResSuccessTemplate.builder().build();
@HystrixCommand(fallbackMethod = "fallback",
commandProperties =
// 隔离策略,有THREAD和SEMAPHORE
// THREAD - 它在单独的线程上执行,并发请求受线程池中的线程数量的限制
// SEMAPHORE - 它在调用线程上执行,并发请求受到信号量计数的限制
@HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
// 开启超时时间,默认值:true
@HystrixProperty(name = "execution.timeout.enabled", value = "true"),
// 超时时间
// 默认值:1000,在THREAD模式下,达到超时时间,可以中断
// 在SEMAPHORE模式下,会等待执行完成后,再去判断是否超时
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
// 在发生超时时是否应中断,默认值:true,THREAD模式有效
@HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "true"),
)
@GetMapping("/getTimeOut")
public ResponseTemplate getTimeOut() throws InterruptedException
TimeUnit.SECONDS.sleep(5);
return ResSuccessTemplate.builder().build();
public ResponseTemplate fallback()
return ResFailTemplate.builder().message("服务降级!").build();
上面我们添加了新的接口,并配置了隔离策略和超时策略,需要注意的是,线程池的隔离可以中断执行方法,信号量的需要等待完成,下面在浏览器调用http://localhost:8080/fallback/getTimeOut
测试
大家也可以把隔离策略换成信号量再测试,可以发现是等待5s后但会的服务降级结果。
但是现在大家应该能发现一个问题,就是我们没写一个接口都要声明@HystrixCommand以及其中的好多参数,比如超时时间和隔离策略我们对全部的接口都适用,此时我们就可以把配置写到配置文件中:
hystrix:
command:
default:
execution:
timeout:
enabled: true #是否应该有超时
isolation: # 隔离策略
#隔离策略,有THREAD 、SEMAPHORE,
#THREAD - 它在单独的线程上执行,并发请求受线程池中的线程数量的限制
#SEMAPHORE - 它在调用线程上执行,并发请求受到信号量计数的限制
strategy: THREAD
semaphore: #信号量
maxConcurrentRequests: 100 #配置信号量的大小,当最大并发请求数达到该设置值,后续的请求将会被拒绝
thread:
timeoutInMilliseconds: 2000 #服务调用超时时间,THREAD隔离模式下是请求超时是会取消调用线程从而立即返回的,SEMAPHORE模式下会等待响应回来再判断是否超时。
interruptOnTimeout: true #执行超时的时候,是否需要将他中断
interruptOnCancel: true #是否在方法执行被取消时中断方法
在服务的接口只需添加 @HystrixCommand(fallbackMethod = "fallback")
即可,再次调用接口,可以发现是一样的效果:
@HystrixCommand(fallbackMethod = "fallback")
@GetMapping("/getTimeOut")
public ResponseTemplate getTimeOut() throws InterruptedException
TimeUnit.SECONDS.sleep(5);
return ResSuccessTemplate.builder().build();
到这还是有一个问题,我们每个接口又都需要指定fallback方法,如果又100个接口方法,哪岂不要写100个降级方法了,此时我们可以使用@DefaultProperties
来为整个Controller 指定一个默认的降级方法,如果@HystrixCommand
没有指定方法就使用@DefaultProperties
的,下面修改我们的程序:
@RestController
@RequestMapping("/fallback")
@DefaultProperties(defaultFallback = "fallback")
public class TestFallBackController
@HystrixCommand
@GetMapping("/getTest")
public ResponseTemplate getTest() throws InterruptedException
int a = 1 / 0;
return ResSuccessTemplate.builder().build();
@HystrixCommand
@GetMapping("/getTimeOut")
public ResponseTemplate getTimeOut() throws InterruptedException
TimeUnit.SECONDS.sleep(5);
return ResSuccessTemplate.builder().build();
public ResponseTemplate fallback()
return ResFailTemplate.builder().message("服务降级!").build();
调用其中一个接口,可以看出使用了fallback降级方法。
喜欢的小伙伴可以关注我的个人微信公众号,获取更多学习资料!
以上是关于SpringCloud H版 Hystrix 介绍及服务降级讲解的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud H版 Hystrix dashboard 可视化监控使用
Spring Cloud:Hystrix 监控数据聚合 TurbineFinchley 版
Spring Cloud:Hystrix 监控面板Finchley 版
深入浅出SpringCloud原理及实战「Netflix系列之Hystrix」针对于限流熔断组件Hystrix的基本参数和实现原理介绍分析