Spring Cloud Hystrix 服务容错

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框架自动地为这个函数实现了依赖隔离。所以依赖隔离,服务降级在使用时候都是一体化实现的,这样就可以实现服务容错保护。在编程模型上就会非常方便。

服务熔断