zoukankan      html  css  js  c++  java
  • 服务熔断之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
    

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

  • 相关阅读:
    1.python的Helloword
    java实现多个属性排序---按照实体的多种属性值进行排序(ComparableComparator/ComparatorChain)
    Spring Boot 2.X(一):入门篇
    Nginx开启Gzip压缩提升页面加载速度
    QQ第三方授权登录OAuth2.0实现(Java)
    Windows下IIS搭建Ftp服务器
    【Java】支付宝获取人脸采集认证的图片base64格式
    【SpingBoot】spring静态工具类注入问题
    【linux】Tomcat 安装
    【linux】jdk安装及环境变量配置
  • 原文地址:https://www.cnblogs.com/markLogZhu/p/13500623.html
Copyright © 2011-2022 走看看