服务熔断之Hystrix

一、Hystrix

1.1 Hystrix 介绍

Hystrix 是一个用于分布式系统的延迟和容错的开源库。Hystrix 实现了断路器模式,当某个服务发生故障时,通过断路器的监控,给调用方返回一个错误响应,而不是长时间的等待,这样就不会使得调用方由于长时间得不到响应而占用线程,从而防止故障的蔓延。Hystrix 具备服务降级、服务熔断、线程隔离、请求缓存、请求合并及服务监控等强大功能。

1.2 Hystrix设计原则是什么

  • 防止任何单个依赖项耗尽所有容器(如Tomcat)用户线程。
  • 甩掉包袱,快速失败而不是排队。
  • 在任何可行的地方提供回退,以保护用户不受失败的影响。
  • 使用隔离技术(如隔离板、泳道和断路器模式)来限制任何一个依赖项的影响。
  • 通过近实时的度量、监视和警报来优化发现时间。
  • 通过配置的低延迟传播来优化恢复时间。
  • 支持对Hystrix的大多数方面的动态属性更改,允许使用低延迟反馈循环进行实时操作修改。
  • 避免在整个依赖客户端执行中出现故障,而不仅仅是在网络流量中。

1.3 Hystrix是如何实现它的目标的

  1. 用一个 HystrixCommand 或者 HystrixObservableCommand 包装所有的对外部系统(或者依赖)的调用,典型地它们在一个单独的线程中执行
  2. 调用超时时间比你自己定义的阈值要长。有一个默认值,对于大多数的依赖项你是可以自定义超时时间的。
  3. 为每个依赖项维护一个小的线程池(或信号量);如果线程池满了,那么该依赖性将会立即拒绝请求,而不是排队。
  4. 调用的结果有这么几种:成功、失败(客户端抛出异常)、超时、拒绝。
  5. 在一段时间内,如果服务的错误百分比超过了一个阈值,就会触发一个断路器来停止对特定服务的所有请求,无论是手动的还是自动的。
  6. 当请求失败、被拒绝、超时或短路时,执行回退逻辑。
  7. 近实时监控指标和配置变化。

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;
    }    
}       
  1. 启动服务

访问 http://localhost:8005/order/getPrice?productId=123,返回如下结果:

100

停止 price-service ,再次访问 http://localhost:8005/order/getPrice?productId=123,返回如下结果:

0

可以发现已经发生了服务降级。

2.4 结合 Feign 使用

  1. 在配置文件中开启熔断模式
feign:
  hystrix:
    # 开启熔断器
    enabled: true
  1. 新增失败降级回调类
@Component
public class PriceServiceFallback implements PriceService {

    @Override
    public BigDecimal getPrice(String productId) {
        System.out.println("服务调用失败");
        return BigDecimal.ZERO;
    }
}
  1. @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);

}
  1. 启动服务

访问 http://localhost:8005/order/getPrice?productId=123,返回如下结果:

100

停止 price-service ,再次访问 http://localhost:8005/order/getPrice?productId=123,返回如下结果:

0

可以发现已经发生了服务降级。

posted @ 2020-08-14 10:06  MarkLogZhu  阅读(187)  评论(0)    收藏  举报