Spring Cloud Netflix微服务开发(三) - 使用Hystrix实现微服务的容错处理

1. 什么是微服务容错

1-1) 高并发场景问题描述

  • 服务提供者响应非常缓慢
  • 服务消费者的请求就会被强制等待, 直到提供者响应超时
  • 在高负载的场景下, 不做任何处理会导致服务消费者的资源耗尽甚至整个系统的崩溃

案例:

某电商网站在某个活动发生过载,由于过多的并发请求,导致用户的用户下单的请求延迟很久都没有响应,在等待很长时间后最终失败。许多用户又重新刷新页面并尝试再次下单,进一步增加了服务器的负载,最终整个系统都崩溃了

1-2) 雪崩效应

微服务应用架构由于各个服务之间通过网络进行通信,各个服务之间存在依赖关系,在脆弱的网络环境下,难免存在服务的级联故障

  • 我们常把基础服务故障导致的级联故障的现象称为雪崩效应

1-3) 容错原理

一个基本的容错机制应该实现以下几点:

  • 为网络请求设置超时

  • 使用断路器模式

有点像电路的断路机制,当电流过载(功率过大/短路),需要跳闸,以保护电路的安全

  • 微服务的断路器模式

    正常情况下,断路器关闭

    当一段时间内,请求失败率达到一定阈值(错误率百分比/每分钟次数),
    断路器就会打开,不再去请求依赖的服务

    断路器打开一段时间后,会自动进入“半开”状态。此时,可允许一个请求访问依赖的服务,
    如果调用成功,则关闭断路器;否则继续保持打开状态。

 

2. 使用Hystrix实现容错

2-1) Hystrix简介

Hystrix是Netflix开源的一个实现了超时机制和断路器模式的工具类库, 它支持延迟和容错库,用于隔离访问远程系统,服务或者第三方库,防止级联失败,从而提升系统的可用性和容错性。

2-2) Hystrix实现机制

  • 包裹请求

使用HystrixCommand(或HystrixObservableCommand)包裹对依赖的调用逻辑,每个命令在独立的线程中执行(命令模式)

  • 跳闸机制

错误率/阈值 -> 停止请求服务一段时间

  • 资源隔离

Hystrix为每个依赖的服务都维护了一个小型的线程池。如果该线程池已满,发往该服务的请求就会被立即拒绝,而不是排队等候,从而加速失败的判定

  • 监控

Hystrix提供近乎实时的各个指标监控(成功/失败/超时/被拒绝请求)

  • 回退机制

当请求失败/超时/被拒绝/断路器打开的时候,可以执行由开发人员自行定义的回退逻辑,通常就是一个缺省值

  • 自我修复(Self Heal)

断路器打开一段时间后会自动进入“半开”状态

 

3. Hystrix实战代码

3-1)添加依赖


  org.springframework.cloud
  spring-cloud-starter-netflix-hystrix

3-2) 启动类添加注解

@EnableCircuitBreaker或@EnableHystrix

ConsumerMovieApplication.java

@EnableDiscoveryClient
@SpringBootApplication
@EnableCircuitBreaker
public class ConsumerMovieApplication {
  @Bean
  @LoadBalanced
  public RestTemplate restTemplate() {
    return new RestTemplate();
  }

  public static void main(String[] args) {
    SpringApplication.run(ConsumerMovieApplication.class, args);
  }
}

3-3) 通过@HystrixCommand指定回调方法来使某个方法具备容错能力

MovieController.java

@RestController
@RequestMapping("movie")
public class MovieController {
  private static final Logger LOGGER = LoggerFactory.getLogger(MovieController.class);
  @Autowired
  private RestTemplate restTemplate;
  @Autowired
  private LoadBalancerClient loadBalancerClient;

  @HystrixCommand(fallbackMethod = "findByIdFallback")
  @GetMapping("/user/{id}")
  public User findById(@PathVariable Long id) {
    return this.restTemplate.getForObject("http://microservice-provider-user/user/" + id, User.class);
  }

  public User findByIdFallback(Long id) {
    User user = new User();
    user.setId(-1L);
    user.setName("默认用户");
    return user;
  }
}

 

4. 测试

4-1) 启动eureka
4-2) 启动microservice-provider-user
4-3) 启动microservice-consumer-movie-ribbon-hystrix
 

image.png

 

4-4) 停止microservice-provider-user

image.png

本文的github代码地址:

https://github.com/davidgjy/springcloud-learn/tree/master/3_hystrix

你可能感兴趣的:(Spring Cloud Netflix微服务开发(三) - 使用Hystrix实现微服务的容错处理)