zoukankan      html  css  js  c++  java
  • 一文带大家彻底搞懂Hystrix!

    前言?

    1. Netflix Hystrix断路器是什么?

    Netflix Hystrix是SOA/微服务架构中提供服务隔离、熔断、降级机制的工具/框架。Netflix Hystrix是断路器的一种实现,用于高微服务架构的可用性,是防止服务出现雪崩的利器。

    1. 为什么需要断路器

    在分布式架构中,一个应用依赖多个服务是非常常见的,如果其中一个依赖由于延迟过高发生阻塞,调用该依赖服务的线程就会阻塞,如果相关业务的QPS较高,就可能产生大量阻塞,从而导致该应用/服务由于服务器资源被耗尽而拖垮。

    另外,故障也会在应用之间传递,如果故障服务的上游依赖较多,可能会引起服务的雪崩效应。就跟数据瘫痪,会引起依赖该数据库的应用瘫痪是一样的道理。

    当一个应用依赖多个外部服务,一切都正常的情况下,如下图:

    如果其中一个依赖发生延迟,当前请求就会被阻塞

    出现这种情况后,如果没有应对措施,后续的请求也会被持续阻塞

    每个请求都占用了系统的CPU、内存、网络等资源,如果该应用的QPS较高,那么该应用所以的服务资源会被快速消耗完毕,直至应用死掉。如果这个出问题的依赖(Dependency I),不止这一个应用,亦或是受影响的应用上层也有更多的依赖,那就会带来我们前面所提到的服务雪崩效应。 所以,为了应对以上问题,就需要有支持服务隔离、熔断等操作的工具。

    Hystrix 简介

    1. Hystrix具备哪些能力/优点?

      在通过网络依赖服务出现高延迟或者失败时,为系统提供保护和控制 可以进行快速失败,缩短延迟等待时间和快速恢复:当异常的依赖回复正常后,失败的请求所占用的线程会被快速清理,不需要额外等待 提供失败回退(Fallback)和相对优雅的服务降级机制 提供有效的服务容错监控、报警和运维控制手段

    2. Hystrix 如何解决级联故障/防止服务雪崩?

    • Hystrix将请求的逻辑进行封装,相关逻辑会在独立的线程中执行

    • Hystrix有自动超时策略,如果外部请求超过阈值,Hystrix会以超时来处理

    • Hystrix会为每个依赖维护一个线程池,当线程满载,不会进行线程排队,会直接终止操作

    • Hystrix有熔断机制: 在依赖服务失效比例超过阈值时,手动或者自动地切断服务一段时间 所以,当引入了Hystrix之后,当出现某个依赖高延迟的时候

    Hystrix 工作原理

    1. Hystrix工作流

    1. 创建HystrixCommand 或者 HystrixObservableCommand 对象
    2. 执行命令execute()、queue()、observe()、toObservable()
    3. 如果请求结果缓存这个特性被启用,并且缓存命中,则缓存的回应会立即通过一个Observable对象的形式返回
    4. 检查熔断器状态,确定请求线路是否是开路,如果请求线路是开路,Hystrix将不会执行这个命令,而是直接执行getFallback
    5. 如果和当前需要执行的命令相关联的线程池和请求队列,Hystrix将不会执行这个命令,而是直接执行getFallback
    6. 执行HystrixCommand.run()或HystrixObservableCommand.construct(),如果这两个方法执行超时或者执行失败,则执行getFallback()
    7. Hystrix 会将请求成功,失败,被拒绝或超时信息报告给熔断器,熔断器维护一些用于统计数据用的计数器。这些计数器产生的统计数据使得熔断器在特定的时刻,能短路某个依赖服务的后续请求,直到恢复期结束,若恢复期结束根据统计数据熔断器判定线路仍然未恢复健康,熔断器会再次关闭线路。
    8. 依赖隔离Hystrix采用舱壁隔离模式隔离相互之间的依赖关系,并限制对其中任何一个的并发访问。

    可能会有人有疑问,为什么不依赖于HTTP Client去做容错保护(快速失败、熔断等),而是在访问依赖之外通过线程&线程池隔离的方式做这个断路器(Hystrix)`

    主要是以下几个方面:

    • 不同的依赖执行的频率不同,需要分开来对待
    • 不同的依赖可能需要不同的Client的工具/协议来访问,比如我们可能用HTTP Client,可能用Thrift Client。
    • Client在执行的过程中也可能会出现非网络异常,这些都应该被隔离
    • Client的变化会引起断路器的变化

    SpringCloud:Ribbon + Hystrix应用

    1. 项目中引入Hystrix

    修改pom.xml,引入Spring Cloud Netflix Hystrix

      <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
      </dependency>
    1. 配置Hystrix启动类

    修改启动类Application.java,增加@EnableHystrix注解开启Hystrix

    @EnableHystrix
    @EnableDiscoveryClient
    @SpringBootApplication
    public class Application {

        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }

        @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }
    1. 断路处理实现

    修改TestService.java,增加断路器功能

    • 在index方法上增加注解 @HystrixCommand并通过fallbackMethod参数指定断路后执行的方法
    • 定义断路处理方法,返回服务/操作断路后的提示
    @Service
    public class TestService {

        @Autowired
        private RestTemplate restTemplate;

        @HystrixCommand(fallbackMethod = "indexError")
        public Object index() {
            return restTemplate.getForObject("http://testservice", String.class);
        }

        public Object plus(int numA, int numB) {
            String url = String.format("http://testservice/plus?numA=%s&numB=%s", numA, numB);
            return restTemplate.getForObject(url, String.class);
        }

        public Object indexError() {
            return "{\"code\": 999,\"message\": \"服务断路\"}";
        }
    }
    1. 断路处理测试

    启动 Application 项目, 访问:http://localhost:8604/ti ,将看到

    {
      "code": 0,
      "message""hello",
      "content": null,
      "serviceName""testservice",
      "host""localhost:8602"
    }

    关闭testservice,然后再访问 http://localhost:8604/ti ,将看到

    {
      "code": 999,
      "message""服务断路"
    }

    至此完成Ribbon+Hystrix的熔断。

    SpringCloud:Feign + Hystrix应用

    1. 开启Hystrix 修改application.yml,开启Hystrix
    feign:
      hystrix:
        enabled: true
    1. 断路处理实现

    新建 TestServiceHystrix.java作为TestService的断路处理实现


    @Component
    public class TestServiceHystrix implements TestService {

        @Override
        public String indexService() {
            return "{\"code\": 999,\"message\": \"服务断路\"}";
        }

        @Override
        public Result plusService(int numA, int numB) {
            Result result = new Result();
            result.setCode(999);
            result.setMessage("服务断路");
            return new Result();
        }

        @Override
        public Result plusabService(Plus plus) {
            Result result = new Result();
            result.setCode(999);
            result.setMessage("服务断路");
            return new Result();
        }

        @Override
        public Result plus2Service(Plus plus) {
            Result result = new Result();
            result.setCode(999);
            result.setMessage("服务断路");
            return new Result();
        }
    }
    1. 修改TestService,指定fallback类
    @FeignClient(value = "testservice", fallback = TestServiceHystrix.class)
    public interface TestService {

        @RequestMapping(value = "/", method = RequestMethod.GET)
        String indexService();

        @RequestMapping(value = "/plus", method = RequestMethod.GET)
        Result plusService(@RequestParam(name = "numA") int numA, @RequestParam(name = "numB") int numB);

        @RequestMapping(value = "/plus", method = RequestMethod.POST, consumes = "application/json")
        Result plusabService(Plus plus);

        @RequestMapping(value = "/plus2", method = RequestMethod.POST)
        Result plus2Service(@RequestBody Plus plus);

    }
    1. 启动 feign Application 项目
    • 访问:http://localhost:8605/ti ,将看到
    {
      "code": 0,
      "message""hello",
      "content": null,
      "serviceName""testservice",
      "host""localhost:8602"
    }
    • 关闭testservice,然后再访问 http://localhost:8605/ti ,将看到
    {
      "code": 999,
      "message""服务断路"
    }

    至此完成Feign+Hystrix的熔断。

    结束

    欢迎关注公众号! 公众号回复:入群 ,扫码加入我们交流群! 扫码关注公众号获取更多学习资料

  • 相关阅读:
    cmcc_simplerop
    WeiFenLuo.winFormsUI.Docking.dll的使用
    MySQL转换Oracle的七大注意事项
    icsharpcode
    详细介绍IIS7基于WAS 部署WCF服务《收藏》
    Win2008 IIS7日期格式更改方法 《转》
    SVCUtil使用说明(生成代理类)《收藏》
    Oracle中的高效语句
    WCF配置文件全攻略《收藏》
    设计高效合理的MySQL查询语句
  • 原文地址:https://www.cnblogs.com/1ssqq1lxr/p/14631032.html
Copyright © 2011-2022 走看看