一、Hystrix
1.1 Hystrix 介绍
Hystrix 是一个用于分布式系统的延迟和容错的开源库。Hystrix 实现了断路器模式,当某个服务发生故障时,通过断路器的监控,给调用方返回一个错误响应,而不是长时间的等待,这样就不会使得调用方由于长时间得不到响应而占用线程,从而防止故障的蔓延。Hystrix 具备服务降级、服务熔断、线程隔离、请求缓存、请求合并及服务监控等强大功能。
1.2 Hystrix设计原则是什么
- 防止任何单个依赖项耗尽所有容器(如Tomcat)用户线程。
- 甩掉包袱,快速失败而不是排队。
- 在任何可行的地方提供回退,以保护用户不受失败的影响。
- 使用隔离技术(如隔离板、泳道和断路器模式)来限制任何一个依赖项的影响。
- 通过近实时的度量、监视和警报来优化发现时间。
- 通过配置的低延迟传播来优化恢复时间。
- 支持对Hystrix的大多数方面的动态属性更改,允许使用低延迟反馈循环进行实时操作修改。
- 避免在整个依赖客户端执行中出现故障,而不仅仅是在网络流量中。
1.3 Hystrix是如何实现它的目标的
- 用一个 HystrixCommand 或者 HystrixObservableCommand 包装所有的对外部系统(或者依赖)的调用,典型地它们在一个单独的线程中执行
- 调用超时时间比你自己定义的阈值要长。有一个默认值,对于大多数的依赖项你是可以自定义超时时间的。
- 为每个依赖项维护一个小的线程池(或信号量);如果线程池满了,那么该依赖性将会立即拒绝请求,而不是排队。
- 调用的结果有这么几种:成功、失败(客户端抛出异常)、超时、拒绝。
- 在一段时间内,如果服务的错误百分比超过了一个阈值,就会触发一个断路器来停止对特定服务的所有请求,无论是手动的还是自动的。
- 当请求失败、被拒绝、超时或短路时,执行回退逻辑。
- 近实时监控指标和配置变化。
1.4 Hystrix 使用方法
通过在方法上使用注解 @HystrixCommand ,常用参数:
* fallbackMethod:指定服务降级处理方法;
* ignoreExceptions:忽略某些异常,不发生服务降级;
* commandKey:命令名称,用于区分不同的命令;
* groupKey:分组名称,Hystrix会根据不同的分组来统计命令的告警及仪表盘信息;
* threadPoolKey:线程池名称,用于划分线程池。
二、Hystrix 使用
注:基于 [SpringCloud之项目初始化 之上操作。
2.1 在 pom 文件中新增 Hystrix 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2.2 开启断路器功能
在 OrderServiceApplication 中添加 @EnableCircuitBreaker 注解启用 Hystrix 断路器功能
@EnableCircuitBreaker
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
2.3 简单应用
1) 新增失败降级回调方法
@RestController
@RequestMapping("/order")
public class OrderController {
private final RestTemplate restTemplate;
private final PriceService priceService;
public OrderController(RestTemplate restTemplate, PriceService priceService) {
this.restTemplate = restTemplate;
this.priceService = priceService;
}
@GetMapping("/getPrice")
@HystrixCommand(fallbackMethod = "fallbackMethod")
public BigDecimal getPrice(String productId) {
final BigDecimal price = restTemplate.getForObject("http://PRICE-SERVICE/price/getPrice/" + productId, BigDecimal.class);
return price;
}
public BigDecimal fallbackMethod(@PathVariable("productId") String productId) {
System.out.println("服务调用失败");
return BigDecimal.ZERO;
}
@GetMapping("/getPrice02")
public BigDecimal getPrice02(String productId) {
final BigDecimal price = priceService.getPrice(productId);
return price;
}
}
- 启动服务
访问 http://localhost:8005/order/getPrice?productId=123
,返回如下结果:
100
停止 price-service ,再次访问 http://localhost:8005/order/getPrice?productId=123
,返回如下结果:
0
可以发现已经发生了服务降级。
2.4 结合 Feign 使用
- 在配置文件中开启熔断模式
feign:
hystrix:
# 开启熔断器
enabled: true
- 新增失败降级回调类
@Component
public class PriceServiceFallback implements PriceService {
@Override
public BigDecimal getPrice(String productId) {
System.out.println("服务调用失败");
return BigDecimal.ZERO;
}
}
- 在 @FeignClient 中指定降级回调类
@FeignClient(value = "PRICE-SERVICE", path = "/price", fallback = PriceServiceFallback.class)
public interface PriceService {
@RequestMapping(value = "/getPrice/{productId}", method = RequestMethod.GET)
BigDecimal getPrice(@PathVariable("productId") String productId);
}
- 启动服务
访问 http://localhost:8005/order/getPrice?productId=123
,返回如下结果:
100
停止 price-service ,再次访问 http://localhost:8005/order/getPrice?productId=123
,返回如下结果:
0
可以发现已经发生了服务降级。