Spring Cloud Hystrix
在微服务架构中,我们将系统拆分成了一个个的服务单元,各单元应用间通过服务注册与订阅的方式互相依赖。由于每个单元都在不同的进程中运行,如果某个服务不可用,可能导致级联故障,造成整个系统不可用的情况(雪崩效应)。为了解决这样的问题,产生了断路器等一系列的服务保护机制。
简介
Spring Cloud Hystrix,它是一个基于 Netflix 的开源框架,具有如下功能:
- 服务降级
- 依赖隔离
- 服务熔断
- 监控(Hystrix Dashboard)
实现一个 Hystrix Server
添加依赖
1
2
3
4
| <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
|
添加注解
1
2
3
4
5
6
7
8
| @EnableCircuitBreaker
@EnableDiscoveryClient
@SpringBootApplication
public class HystrixApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixApplication.class, args);
}
}
|
配置文件
1
2
3
4
5
6
7
8
9
10
11
| spring:
application:
name: hystrix-server
server:
port: 8080
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
|
Hystrix 应用
服务降级
假设现在有一个接口 /user/{id}
获取用户信息。
1
2
3
| public ResultVo<UserInfo> getUserInfo(@PathVariable String id) {
return userService.getUserInfo(id);
}
|
在 UserService 中添加调用方法的服务降级。
1
2
3
4
5
6
7
8
9
10
11
12
| @HystrixCommand(fallbackMethod = "userFallback")
public ResultVo<UserInfo> getUserInfo(String id) {
// 正常的服务调用和业务 此处以 restTemplate 为例
// ...
return restTemplate.getForObject(url + "/user/{1}", ResultVo.class, id);
}
public ResultVo<UserInfo> userFallback() {
// ...
// 处理服务降级需要返回的内容
}
|
服务降级 OpenFiegn
配置文件
1
2
3
| feign:
hystrix:
enabled: true
|
OpenFeign Client 端实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| @FeignClient(
name = "user", // 远程服务名
fallback = UserClientFallback.class // 指定 当服务降级时,采用的方法
)
public interface UserClient {
@GetMapping("/user/{id}")
ResultVo<UserInfo> getUserInfo(@PathVariable String id);
}
---
// 实现 UserClient 接口
@Component
public class UserClientFallback implements UserClient {
@Override
ResultVo<UserInfo> getUserInfo(@PathVariable String id) {
// ...
// 实现降级内容
}
}
|
依赖隔离
SpringCloud Hystrix 的 依赖隔离 类似于docker的“舱壁模式”。
docker通过”舱壁模式”实现进程隔离,使得容器之间互不影响。
而Hystrix使用该模式实现:“线程池隔离”,会为每一个HystrixCommand创建一个独立线程池,这样就算某个在Hystrix包装下的依赖服务出现延迟过高情况,也只是对该依赖服务的调用产生影响,并不会拖慢其他服务。
使用 @HystrixCommand 来将某个函数包装成了 Hystrix 命令时,Hystrix框架自动地为这个函数实现了依赖隔离。所以依赖隔离,服务降级在使用时候都是一体化实现的,这样就可以实现服务容错保护。在编程模型上就会非常方便。
服务熔断