zoukankan      html  css  js  c++  java
  • Hystrix 实现服务熔断与降级

    本文为博主原创,未经允许不得转载:

    目录:

      1. 服务雪崩,服务熔断,服务降级概念

      2. Hystrix 概念

      3. Hystrix 使用及默认配置

      4. @HystrixCommond 注解使用

      5. 常用熔断器配置

      1. 服务雪崩,服务熔断,服务降级

         服务雪崩:因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程,就叫服务雪崩效应。如 A 服务调用 B 服务,B服务再调用C服务,

            当C服务不可用,且大量请求从 A端请求到C端时,因为C 服务不可用,会导致线程池里所有线程都因等待响应而被阻塞, 从而造成服务雪崩

          服务熔断:当下游的服务因为某种原因突然变得不可用或响应过慢,上游服务为了保证自己整体服务的可用性,不再继续调用目标服务,直接返回,

            快速释放资源。如果目标服务情况好转则恢复调用。需要说明的是熔断其实是一个框架级的处理,那么这套熔断机制的设计,基本上业内用

            的是断路器模式,与熔断器是相同的原理。

         服务降级:就是当某个服务熔断之后,服务将不再被调用,此时客户端可以自己准备一个本地的fallback(回退)回调,返回一个缺省值。

            使用场景:

              1. 当系统服务遇到双十一,大促销等场景时,可对不重要的服务进行降级,释放出服务器的资源,优先保障核心业务

              2. 当下游的服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速返回给用户!

            服务熔断也是服务降级的一种保护措施,还包括:限流降级,开关降级

      2. Hystrix 基本概念:

        Hystrix并不是Spring的,而是NetFlix公司开源的,提供超时机制,限流,熔断,降级最全面的实现.

        原理:通过“命令模式”的方式,继承(HystrixCommand类)来包裹具体的服务调用逻辑(run方法), 并在命令模式中添加了服务调用失败后的降级逻辑(getFallback)

        资源隔离:线程隔离,信号量隔离
        线程隔离:Hystrix会给每一个Command分配一个单独的线程池,这样在进行单个服务调用的时候,就可以在独立的线程池里面进行,而不会对其他线程池造成影响
        信号量隔离:客户端需向依赖服务发起请求时,首先要获取一个信号量才能真正发起调用,由于信号量的数量有限,当并发请求量超过信号量个数时,后续的  
            请求都会直接拒绝,进入fallback流程。信号量隔离主要是通过控制并发请求量,防止请求线程大面积阻塞,从而达到限流和防止雪崩的目的。
      

      3. Hystrix 使用及默认配置

        3.1 添加 pom 依赖:

          <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>
            <!--hystrix官网-->
            <dependency>
                <groupId>com.netflix.hystrix</groupId>
                <artifactId>hystrix-core</artifactId>
                <version>1.5.18</version>
            </dependency>
    
            <dependency>
                <groupId>com.netflix.hystrix</groupId>
                <artifactId>hystrix-javanica</artifactId>
                <version>1.5.18</version>
            </dependency>

        3.2 默认配置及常用配置:

          3.2.1 线程隔离配置:

          hystrix.command.default.execution.isolation.strategy 隔离策略,默认是Thread, 可选Thread|Semaphore

          hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 命令执行超时时间,默认1000ms

          hystrix.command.default.execution.timeout.enabled 执行是否启用超时,默认启用true

          hystrix.command.default.execution.isolation.thread.interruptOnTimeout 发生超时是是否中断,默认true

           3.2.2 信号量隔离配置 

          hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests  最大并发请求数,默认10,该参数当使用

            ExecutionIsolationStrategy.SEMAPHORE策略时才有效。如果达到最大并发请求数,请求会被拒绝。理论上选择semaphore size的原则和

            选择thread size一致,但选用semaphore时每次执行的单元要比较小且执行速度快(ms级别),否则的话应该用thread。

          hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests  如果并发数达到该设置值,请求会被拒绝和抛出
            异常并且fallback不会被调用。默认10

          3.2.3 ThreadPool 相关参数

          hystrix.threadpool.default.coreSize 并发执行的最大线程数,默认10

          hystrix.threadpool.default.maxQueueSize   BlockingQueue的最大队列数,当设为-1,会使用SynchronousQueue,值为正时使用LinkedBlcokingQueue。
            该设置只会在初始化时有效,之后不能修改threadpool的queue size,除非reinitialising thread executor。默认-1。
          hystrix.threadpool.default.queueSizeRejectionThreshold 即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝。
            因为maxQueueSize不能被动态修改,这个参数将允许我们动态设置该值。if maxQueueSize == ­1,该字段将不起作用
     

      4. @HystrixCommand 的使用

        4.1 在需要熔断与降级的方法上使用 @HystrixCommand  注解

     @HystrixCommand(fallbackMethod = "onError",
                ignoreExceptions = ClassNotFoundException.class,
                commandProperties = {
                        @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
                        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),
                        @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
                        @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2")},
                threadPoolProperties = {
                        @HystrixProperty(name = "coreSize", value = "5"),
                        @HystrixProperty(name = "maximumSize", value = "5"),
                        @HystrixProperty(name = "maxQueueSize", value = "10")
                })
        @RequestMapping("/sayHello")
        public String sayHello(String name) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Hello, " + name;
        }
    
        /**
         * 如果fallback方法的参数和原方法参数个数不一致,则会出现FallbackDefinitionException: fallback method wasn't found
         */
        public String onError(String name) {
            return "Error!!!" + name;
        }

      4.2 添加 HystrixCommand 注解使用的切面配置

    import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
    import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
    import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
    import org.springframework.boot.web.servlet.ServletContextInitializer;
    import org.springframework.boot.web.servlet.ServletRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.servlet.Servlet;
    
    @Configuration
    public class HystrixConfig {
    
        /**
         * A {@link ServletContextInitializer} to register {@link Servlet}s in a Servlet 3.0+ container.
         */
        @Bean
        public ServletRegistrationBean hystrixMetricsStreamServlet() {
            return new ServletRegistrationBean(new HystrixMetricsStreamServlet(), "/hystrix.stream");
        }
    
        /**
         * AspectJ aspect to process methods which annotated with {@link HystrixCommand} annotation.
         *
         * {@link HystrixCommand} annotation used to specify some methods which should be processes as hystrix commands.
         */
        @Bean
        public HystrixCommandAspect hystrixCommandAspect() {
            return new HystrixCommandAspect();
        }
    
    }

      5. 常用熔断器配置

        Circuit Breaker一共包括如下6个参数。
          1、circuitBreaker.enabled
            是否启用熔断器,默认是TURE。
          2、circuitBreaker.forceOpen
            熔断器强制打开,始终保持打开状态。默认值FLASE。
          3、circuitBreaker.forceClosed
            熔断器强制关闭,始终保持关闭状态。默认值FLASE。
          4、circuitBreaker.errorThresholdPercentage
            设定错误百分比,默认值50%,例如一段时间(10s)内有100个请求,其中有55个超时或者异常返回了,那么这段时间内的错误百分比是55%,大于了默认值50%,这种情况下触发熔断器-打开。
          5、circuitBreaker.requestVolumeThreshold
            默认值20.意思是至少有20个请求才进行errorThresholdPercentage错误百分比计算。比如一段时间(10s)内有19个请求全部失败了。错误百分比是100%,但熔断器不会打开,因为requestVolumeThreshold的值是20. 这个参数非常重要,熔断器是否打开首先要满足这个条件
          6、circuitBreaker.sleepWindowInMilliseconds
            半开试探休眠时间,默认值5000ms。当熔断器开启一段时间之后比如5000ms,会尝试放过去一部分流量进行试探,确定依赖服务是否恢复。
  • 相关阅读:
    20.logging模块
    21.django中间件源码阅读
    18.configparser模块
    15.DRF学习以及相关源码阅读
    19.tcp_upd
    13.关于继承封装,以及反射
    16.html转pdf的一个小示例
    14.django返回展示一张图片
    GridView列标题修改
    ~为服务器端根目录符
  • 原文地址:https://www.cnblogs.com/zjdxr-up/p/15085493.html
Copyright © 2011-2022 走看看