Spring Cloud Netflix-微服务容错(Hystrix)


前言

以下类容来自书籍《Spring Cloud与Docker微服务架构实战(第2版)》


简介

容错,顾名思义是指当微服务出错时可以有一个兜底的方案,从而不会使整体服务无法工作

雪崩效应

上图服务D是服务C的提供者,服务C是服务A、B的提供者。当服务D故障,会导致C调用失败,紧接着会导致服务A、B调用失败。

断路器容错

当服务调用失败的次数达到某个阈值时,断路器打开,不再请求原先依赖的服务,而转为调用兜底服务或者快速失败。断路器也会自行修复,每隔一段时间会进入半开状态 此时断路器会允许一个请求去调用原先的依赖服务,如调用成功,则关闭断路器,若调用失败则保持打开状态。

Hystrix实现容错

    包裹请求,使用HystrixCommand包裹对依赖的调用逻辑,每个命令在独立的线程中,使用了。 跳闸机制,当请求次数达到阈值时,Hystrix会停止请求该服务一段时间。 资源隔离,Hystrix为每个依赖都维护一个小型线程池(或信号量)。线程池已满则拒接请求 监控,实时监控运行指标和配置变化 回退,当请求失败或断路器打开时,执行自定义的回退逻辑。 自我修复,断路器打开一段时间后,进入半开状态。

整合

添加依赖

<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>

启动类增加注解@EnableCircuitBreaker 修改控制器,@HystrixCommand(fallbackMethod = “findByIdFallback”)指定回退方法。

@RestController
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/" + id, User.class);
  }

  public User findByIdFallback(Long id) {
          
   
  	LOGGER.error("进入回退方法,异常:",throwable);
    User user = new User();
    user.setId(-1L);
    user.setName("默认用户");
    return user;
  }

  @GetMapping("/log-user-instance")
  public void logUserInstance() {
          
   
    ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
    // 打印当前选择的是哪个节点
    MovieController.LOGGER.info("{}:{}:{}", serviceInstance.getServiceId(), serviceInstance.getHost(), serviceInstance.getPort());
  }
}

启动Eureka,服务提供者,服务调用者。调用服务调用者接口http://localhost:8010/user/1,然后将服务提供者关闭,再次请求。 也可使用@HystrixCommand(fallbackMethod = “findByIdFallback”,ignoreExceptions = {IllegalArgumentException.class})中的ignoreExceptions属性来忽略某些异常不错回退逻辑处理。


经验分享 程序员 微信小程序 职场和发展