1.什么是Hystrix
Spring Cloud Hystrix 是一款优秀的服务容错与保护组件,也是 Spring Cloud 中最重要的组件之一。
Spring Cloud Hystrix 是基于 Netflix 公司的开源组件 Hystrix 实现的,它提供了熔断器功能,能够有效地阻止分布式微服务系统中出现联动故障,以提高微服务系统的弹性。Spring Cloud Hystrix 具有服务降级、服务熔断、线程隔离、请求缓存、请求合并以及实时故障监控等强大功能。
2.Hystrix的作用
在微服务系统中,Hystrix 能够帮助我们实现以下目标:
- 提供降级(FallBack)方案:在请求失败后,提供一个设计好的降级方案,通常是一个兜底方法,当请求失败后即调用该方法。
- 防止故障扩散:使用熔断机制,防止故障扩散到其他服务。
- 监控功能:提供熔断器故障监控组件 Hystrix Dashboard,随时监控熔断器的状态。
- 保护线程资源:防止单个服务的故障耗尽系统中的所有线程资源。
快速失败机制:当某个服务发生了故障,不让服务调用方一直等待,而是直接返回请求失败。
3.服务降级
1.什么是服务降级:
在服务器压力剧增时,根据实际业务情况及流量,对一些不重要、不紧急的服务进行有策略地不处理或简单处理,从而释放服务器资源以保证核心服务正常运作。
- 当某些服务不可用时,为了避免长时间等待造成服务卡顿或雪崩效应,而主动执行备用的降级逻辑立刻返回一个友好的提示,以保障主体业务不受影响。
2.服务降级发生的场景
- 服务提供者接口抛出异常:触发服务调用者降级逻辑
- 服务提供者接口响应超时:触发服务调用者降级逻辑
- 服务提供者熔断器处于打开状态:触发服务提供者降级逻辑
- 服务调用者线程池资源耗尽:触发服务调用者降级逻辑
3.服务端降级(不常用)
服务提供方为了防止对外提供的接口出现异常,进而导致整体服务出现雪崩效应,而提出的一种兜底方案,从而实现异常情况下得友好返回,而不是整个服务调用链的长时间阻塞进而崩溃4.客户端降级(常用)
客户端降级是较常用的一种解决方案。服务调动方为了防止其调用服务出现响应超时等异常情况,当客户端调用的服务端的服务不可用时,客户端直接进行服务降级处理,避免因为IO阻塞造成线程被长时间不必要的占用4.整合OpenFeign客户端解耦降级步骤(常用)
引入依赖
```xmlorg.springframework.cloud spring-cloud-starter-netflix-hystrix
<a name="tzgqF"></a>
### 编写feign客户端
```java
@Component
@FeignClient(value = "service8")
public interface HystrixService {
@GetMapping("api/v1/service8/5")
String get5();
@GetMapping("api/v1/service8/7")
String get7();
}
编写解耦降级逻辑类
@Component
public class HystrixServiceFallback implements HystrixService{
@Override
public String get5() {
return "触发get5熔断";
}
@Override
public String get7() {
return "触发get7熔断";
}
}
通过FeignClient的fallback属性声明降级逻辑类
@Component
@FeignClient(value = "service8", fallback = HystrixServiceFallback.class)
public interface HystrixService {
@GetMapping("api/v1/service8/5")
String get5();
@GetMapping("api/v1/service8/7")
String get7();
}
启动类添加注解
@EnableFeignClients
@EnableEurekaClient
@SpringBootApplication
public class Service3Application {
public static void main(String[] args) {
SpringApplication.run(Service3Application.class, args);
}
}
添加配置
######################### Ribbon 客户端超时控制 ###################################
ribbon:
ReadTimeout: 7000 #建立连接所用的时间,适用于网络状况正常的情况下,两端两端连接所用的时间
ConnectionTimeout: 7000 #建立连接后,服务器读取到可用资源的时间
######################### 开启feign调用服务端降级 ###################################
feign:
hystrix:
enabled: true
###################### 配置默认请求超时时间 ##########################
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 7000
################### 配置具体方法超时时间########################
HystrixService#get5():
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
PS:
- 在配置中需一起声明ribbon与hystrix的超时时间,缺一不可。否则请求时间超过1s就会触发降级逻辑
- Hystrix 可以为所有方法设置超时时间(单位为毫秒),若请求超时则触发全局的回退方法进行处理:hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=mmm
- Hystrix 还可以为某个特定的服务请求(方法)设置超时时间(单位为毫秒):hystrix.command.xxx#yyy(zzz).execution.isolation.thread.timeoutInMilliseconds=mmm
特定方法超时格式说明如下:
- xxx:为包含该服务方法的类的名称(通常为Feign服务绑定接口的名称)
- yyy:服务方法名,例如 get5() 方法。
- zzz:方法内的参数类型,例如 Integer、String 等等
-
5.服务端降级步骤(不常用)
引入依赖
<!--hystrix 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
对应方法添加降级策略(通常都是用在Service层面)
@GetMapping
@HystrixCommand(fallbackMethod = "fallBack", commandProperties = {@HystrixProperty(
name = "execution.isolation.thread.timeoutInMilliseconds",
value = "5000")
})
public String get() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "1111";
}
启动类添加注解开启服务降级
@EnableCircuitBreaker
@SpringBootApplication
@EnableEurekaClient
public class HystrixApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixApplication.class, args);
}
}
6.客户端耦合降级步骤(不常用)
引入依赖
<!--hystrix 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
在特定方法以及全局类上声明降级方法
@RestController
@RequestMapping("api/v1/service3")
@DefaultProperties(defaultFallback = "defaultFallback") //声明全局降级方法
public class Controller {
@Resource
private HystrixService hystrixService;
@GetMapping("/5")
@HystrixCommand
public String get5() {
return hystrixService.get5();
}
@GetMapping("/7")
@HystrixCommand(fallbackMethod = "fallback") //单独声明降级方法
public String get7() {
return hystrixService.get7();
}
public String fallback(){
return "触发服务降级,请稍后访问!";
}
public String defaultFallback(){
return "触犯默认降级方法!!!!!!!!!!!!!!!!!!";
}
}
HystrixService必须是远程feign调用声明的服务接口
默认降级(defaultFallback)方法必须与其对应的业务方法在同一个类中,否则无法生效。
全局降级方法的优先级较低,只有业务方法没有指定其降级方法时,服务降级时才会触发全局回退方法。若业务方法指定它自己的回退方法,那么在服务降级时,就只会直接触发它自己的回退方法,而非全局回退方法。添加配置
```yaml
################### 开启feign调用服务端降级
feign: hystrix: enabled: true
################ 配置默认请求超时时间
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 7000
################### 配置具体方法超时时间########################
HystrixService#get5():
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
<a name="SLkeU"></a>
### 启动类添加注解
```java
@EnableHystrix
@EnableFeignClients
@EnableEurekaClient
@SpringBootApplication
public class Service3Application {
public static void main(String[] args) {
SpringApplication.run(Service3Application.class, args);
}
}
7.服务熔断
熔断机制是为了应对雪崩效应而出现的一种微服务链路保护机制。
当微服务系统中的某个微服务不可用或响应时间太长时,为了保护系统的整体可用性,熔断器会暂时切断请求对该服务的调用,并快速返回一个友好的错误响应。这种熔断状态不是永久的,在经历了一定的时间后,熔断器会再次检测该微服务是否恢复正常,若服务恢复正常则恢复其调用链路。
熔断共包含三种状态:
- 熔断关闭状态(Closed):当务访问正常时,熔断器处于关闭状态,服务调用方可以正常地对服务进行调用。
- 熔断开启状态(Open):默认情况下,在固定时间内接口调用出错比率达到一个阈值(例如 50%),熔断器会进入熔断开启状态。进入熔断状态后,后续对该服务的调用都会被切断,熔断器会执行本地的降级(FallBack)方法。
- 半熔断状态(Half-Open): 在熔断开启一段时间之后,熔断器会进入半熔断状态。在半熔断状态下,熔断器会尝试恢复服务调用方对服务的调用,允许部分请求调用该服务,并监控其调用成功率。如果成功率达到预期,则说明服务已恢复正常,熔断器进入关闭状态;如果成功率仍旧很低,则重新进入熔断开启状态。
8.Hystrix熔断
在 Spring Cloud 中,熔断机制是通过 Hystrix 实现的。Hystrix 会监控微服务间调用的状况,当失败调用到一定比例时(例如 5 秒内失败 20 次),就会启动熔断机制。
Hystrix 实现服务熔断的步骤如下:
- 当服务的调用出错率达到或超过 Hystix 规定的比率(默认为 50%)后,熔断器进入熔断开启状态。
- 熔断器进入熔断开启状态后,Hystrix 会启动一个休眠时间窗,在这个时间窗内,该服务的降级逻辑会临时充当业务主逻辑,而原来的业务主逻辑不可用。
- 当有请求再次调用该服务时,会直接调用降级逻辑快速地返回失败响应,以避免系统雪崩。
- 当休眠时间窗到期后,Hystrix 会进入半熔断转态,允许部分请求对服务原来的主业务逻辑进行调用,并监控其调用成功率。
- 如果调用成功率达到预期,则说明服务已恢复正常,Hystrix 进入熔断关闭状态,服务原来的主业务逻辑恢复;否则 Hystrix 重新进入熔断开启状态,休眠时间窗口重新计时,继续重复第 2 到第 5 步
9.Hystrix熔断机制的实现
熔断个人认为一般是从服务提供者的角度去考虑引入依赖
<!--hystrix 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
在具体方法添加@HystrixCommand标签
```java @GetMapping(“/{id}”) @HystrixCommand(fallbackMethod = “fallback”, commandProperties = { //以下参数在 HystrixCommandProperties 类中有默认配置 @HystrixProperty(name = “circuitBreaker.enabled”, value = “true”), //是否开启熔断器 @HystrixProperty(name = “circuitBreaker.sleepWindowInMilliseconds”, value = “10000”), //休眠时间窗口期 @HystrixProperty(name = “metrics.rollingStats.timeInMilliseconds”,value = “5000”), //统计时间窗 @HystrixProperty(name = “circuitBreaker.requestVolumeThreshold”, value = “10”), //统计时间窗内请求次数 @HystrixProperty(name = “circuitBreaker.errorThresholdPercentage”, value = “60”), //在统计时间窗口期以内,请求失败率达到 60% 时进入熔断状态 }) public String getInt(@PathVariable Integer id) { if (id < 0) {
} else {throw new RuntimeException("不能小于0");
} }return "干得漂亮:" + id;
public String fallback(Integer id){ return “进入熔断逻辑了SB!”; }
**PS:fallback方法参数必须和具体业务方法参数、返回值一致,不然会报错**
<a name="v0GVC"></a>
### 启动类添加注解
```java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableCircuitBreaker
@SpringBootApplication
@EnableEurekaClient
public class Service4Application {
public static void main(String[] args) {
SpringApplication.run(Service4Application.class, args);
}
}
@HystrixCommand标签参数说明:
参数 | 描述 |
---|---|
metrics.rollingStats.timeInMilliseconds | 统计时间窗。 |
circuitBreaker.requestVolumeThreshold | 请求总数阀值。 在统计时间窗内,请求总数必须到达一定的数量级,Hystrix 才可能会将熔断器打开进入熔断开启转态,而这个请求数量级就是 请求总数阀值。Hystrix 请求总数阈值默认为 20,这就意味着在统计时间窗内,如果服务调用次数不足 20 次,即使所有的请求都调用出错,熔断器也不会打开。 |
circuitBreaker.errorThresholdPercentage | 错误百分比阈值。 当请求总数在统计时间窗内超过了请求总数阀值,且请求调用出错率超过一定的比例,熔断器才会打开进入熔断开启转态,而这个比例就是错误百分比阈值。错误百分比阈值设置为 50,就表示错误百分比为 50%,如果服务发生了 30 次调用,其中有 15 次发生了错误,即超过了 50% 的错误百分比,这时候将熔断器就会打开。 |
circuitBreaker.sleepWindowInMilliseconds | 休眠时间窗,熔断开启状态持续一段时间后,熔断器会自动进入半熔断状态,这段时间就被称为休眠窗口期。 |
9.Hystrix监控
参考这里:点击这里
10.总结
Hystrix为微服务间系统调用提供了服务降级、服务熔断等容错机制,提高了微服务系统的健壮性
作为服务提供者,通过熔断机制避免了当请求不可用时,造成长时间请求阻塞引发雪崩效应。并且通过熔断窗口期给了服务恢复正常的缓冲时间
作为服务调用者,通过指定fallback实现类,保证了其调用的服务在不可用时,以解耦降级的方式通过降级机制进行一个兜底的友好返回。进而避免调用的服务不可用引发的雪崩效应。
总体上来讲,都是为了提高系统的健壮性以及容错性,保证了整个微服务系统的高可用性