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属性来忽略某些异常不错回退逻辑处理。
