精华内容
下载资源
问答
  • 基于本地缓存的 fallback 降级机制 Hystrix 出现以下四种情况,都会去调用 fallback 降级机制: 断路器处于打开的状态。 资源池已满(线程池+队列 / 信号量)。 Hystrix 调用各种接口,或者访问外部依赖,比如 ...

    基于本地缓存的 fallback 降级机制

    Hystrix 出现以下四种情况,都会去调用 fallback 降级机制:

    • 断路器处于打开的状态。
    • 资源池已满(线程池+队列 / 信号量)。
    • Hystrix 调用各种接口,或者访问外部依赖,比如 MySQL、Redis、Zookeeper、Kafka 等等,出现了任何异常的情况。
    • 访问外部依赖的时候,访问时间过长,报了 TimeoutException 异常。
      降级也就是已备不时之需错误的时候一种解决方案,不能给用户返回一个错误代码给用户看,应该给与一个友好的提示.

    两种最经典的降级机制

    • 纯内存数据
      在降级逻辑中,你可以在内存中维护一个 ehcache,作为一个纯内存的基于 LRU 自动清理的缓存,让数据放在缓存内。如果说外部依赖有异常,fallback 这里直接尝试从 ehcache 中获取数据。
    • 默认值
      fallback 降级逻辑中,也可以直接返回一个默认值。

    HystrixCommand,降级逻辑的书写,是通过实现 getFallback() 接口;而在 HystrixObservableCommand 中,则是实现 resumeWithFallback() 方法。

    现在,我们用一个简单的栗子,来演示 fallback 降级是怎么做的。

    比如,有这么个场景。我们现在有个包含 brandId 的商品数据,假设正常的逻辑是这样:拿到一个商品数据,根据 brandId 去调用品牌服务的接口,获取品牌的最新名称 brandName。

    假如说,品牌服务接口挂掉了,那么我们可以尝试从本地内存中,获取一份稍过期的数据,先凑合着用。

    步骤一:本地缓存获取数据

    本地获取品牌名称的代码大致如下。

    /**
     * 品牌名称本地缓存
     *
     */
    
    public class BrandCache {
    
        private static Map<Long, String> brandMap = new HashMap<>();
    
        static {
            brandMap.put(1L, "Nike");
        }
    
        /**
         * brandId 获取 brandName
         *
         * @param brandId 品牌id
         * @return 品牌名
         */
        public static String getBrandName(Long brandId) {
            return brandMap.get(brandId);
        }
    

    步骤二:实现 GetBrandNameCommand

    在 GetBrandNameCommand 中,run() 方法的正常逻辑是去调用品牌服务的接口获取到品牌名称,如果调用失败,报错了,那么就会去调用 fallback 降级机制。

    这里,我们直接模拟接口调用报错,给它抛出个异常。

    而在 getFallback() 方法中,就是我们的降级逻辑,我们直接从本地的缓存中,获取到品牌名称的数据。

    /**
     * 获取品牌名称的command
     *
     */
    
    public class GetBrandNameCommand extends HystrixCommand<String> {
    
        private Long brandId;
    
        public GetBrandNameCommand(Long brandId) {
            super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("BrandService"))
                    .andCommandKey(HystrixCommandKey.Factory.asKey("GetBrandNameCommand"))
                    .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                            // 设置降级机制最大并发请求数
                            .withFallbackIsolationSemaphoreMaxConcurrentRequests(15)));
            this.brandId = brandId;
        }
    
        @Override
        protected String run() throws Exception {
            // 这里正常的逻辑应该是去调用一个品牌服务的接口获取名称
            // 如果调用失败,报错了,那么就会去调用fallback降级机制
    
            // 这里我们直接模拟调用报错,抛出异常
            throw new Exception();
        }
    
        @Override
        protected String getFallback() {
            return BrandCache.getBrandName(brandId);
        }
    }
    

    FallbackIsolationSemaphoreMaxConcurrentRequests 用于设置 fallback 最大允许的并发请求量,默认值是 10,是通过 semaphore 信号量的机制去限流的。如果超出了这个最大值,那么直接 reject。

    步骤三:CacheController 调用接口

    在 CacheController 中,我们通过 productInfo 获取 brandId,然后创建 GetBrandNameCommand 并执行,去尝试获取 brandName。这里执行会报错,因为我们在 run() 方法中直接抛出异常,Hystrix 就会去调用 getFallback() 方法走降级逻辑。

    @Controller
    public class CacheController {
    
        @RequestMapping("/getProductInfo")
        @ResponseBody
        public String getProductInfo(Long productId) {
            HystrixCommand<ProductInfo> getProductInfoCommand = new GetProductInfoCommand(productId);
    
            ProductInfo productInfo = getProductInfoCommand.execute();
            Long brandId = productInfo.getBrandId();
    
            HystrixCommand<String> getBrandNameCommand = new GetBrandNameCommand(brandId);
    
            // 执行会抛异常报错,然后走降级
            String brandName = getBrandNameCommand.execute();
            productInfo.setBrandName(brandName);
    
            System.out.println(productInfo);
            return "success";
        }
    }
    

    关于降级逻辑的演示,基本上就结束了。

    展开全文
  • 基于本地缓存的 fallback 降级机制 Hystrix 出现以下四种情况,都会去调用 fallback 降级机制: 断路器处于打开的状态。 资源池已满(线程池+队列 / 信号量)。 Hystrix 调用各种接口,或者访问外部依赖,比如 ...

    基于本地缓存的 fallback 降级机制

    Hystrix 出现以下四种情况,都会去调用 fallback 降级机制:

    • 断路器处于打开的状态。
    • 资源池已满(线程池+队列 / 信号量)。
    • Hystrix 调用各种接口,或者访问外部依赖,比如 MySQL、Redis、Zookeeper、Kafka 等等,出现了任何异常的情况。
    • 访问外部依赖的时候,访问时间过长,报了 TimeoutException 异常。

    两种最经典的降级机制

    • 纯内存数据
      在降级逻辑中,你可以在内存中维护一个 ehcache,作为一个纯内存的基于 LRU 自动清理的缓存,让数据放在缓存内。如果说外部依赖有异常,fallback 这里直接尝试从 ehcache 中获取数据。

    • 默认值
      fallback 降级逻辑中,也可以直接返回一个默认值。

    在 HystrixCommand,降级逻辑的书写,是通过实现 getFallback() 接口;而在 HystrixObservableCommand 中,则是实现 resumeWithFallback() 方法。

    现在,我们用一个简单的栗子,来演示 fallback 降级是怎么做的。

    比如,有这么个场景。我们现在有个包含 brandId 的商品数据,假设正常的逻辑是这样:拿到一个商品数据,根据 brandId 去调用品牌服务的接口,获取品牌的最新名称 brandName。

    假如说,品牌服务接口挂掉了,那么我们可以尝试从本地内存中,获取一份稍过期的数据,先凑合着用。

    步骤一:本地缓存获取数据

    本地获取品牌名称的代码大致如下。

    /**
     * 品牌名称本地缓存
     *
     */
    
    public class BrandCache {
    
        private static Map<Long, String> brandMap = new HashMap<>();
    
        static {
            brandMap.put(1L, "Nike");
        }
    
        /**
         * brandId 获取 brandName
         *
         * @param brandId 品牌id
         * @return 品牌名
         */
        public static String getBrandName(Long brandId) {
            return brandMap.get(brandId);
        }

    步骤二:实现 GetBrandNameCommand

    在 GetBrandNameCommand 中,run() 方法的正常逻辑是去调用品牌服务的接口获取到品牌名称,如果调用失败,报错了,那么就会去调用 fallback 降级机制。

    这里,我们直接模拟接口调用报错,给它抛出个异常。

    而在 getFallback() 方法中,就是我们的降级逻辑,我们直接从本地的缓存中,获取到品牌名称的数据。

    /**
     * 获取品牌名称的command
     *
     */
    
    public class GetBrandNameCommand extends HystrixCommand<String> {
    
        private Long brandId;
    
        public GetBrandNameCommand(Long brandId) {
            super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("BrandService"))
                    .andCommandKey(HystrixCommandKey.Factory.asKey("GetBrandNameCommand"))
                    .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                            // 设置降级机制最大并发请求数
                            .withFallbackIsolationSemaphoreMaxConcurrentRequests(15)));
            this.brandId = brandId;
        }
    
        @Override
        protected String run() throws Exception {
            // 这里正常的逻辑应该是去调用一个品牌服务的接口获取名称
            // 如果调用失败,报错了,那么就会去调用fallback降级机制
    
            // 这里我们直接模拟调用报错,抛出异常
            throw new Exception();
        }
    
        @Override
        protected String getFallback() {
            return BrandCache.getBrandName(brandId);
        }
    }

    FallbackIsolationSemaphoreMaxConcurrentRequests 用于设置 fallback 最大允许的并发请求量,默认值是 10,是通过 semaphore 信号量的机制去限流的。如果超出了这个最大值,那么直接 reject。

    步骤三:CacheController 调用接口

    在 CacheController 中,我们通过 productInfo 获取 brandId,然后创建 GetBrandNameCommand 并执行,去尝试获取 brandName。这里执行会报错,因为我们在 run() 方法中直接抛出异常,Hystrix 就会去调用 getFallback() 方法走降级逻辑。

    @Controller
    public class CacheController {
    
        @RequestMapping("/getProductInfo")
        @ResponseBody
        public String getProductInfo(Long productId) {
            HystrixCommand<ProductInfo> getProductInfoCommand = new GetProductInfoCommand(productId);
    
            ProductInfo productInfo = getProductInfoCommand.execute();
            Long brandId = productInfo.getBrandId();
    
            HystrixCommand<String> getBrandNameCommand = new GetBrandNameCommand(brandId);
    
            // 执行会抛异常报错,然后走降级
            String brandName = getBrandNameCommand.execute();
            productInfo.setBrandName(brandName);
    
            System.out.println(productInfo);
            return "success";
        }
    }

    关于降级逻辑的演示,基本上就结束了。

    展开全文
  • 8.hystrix的fallback降级机制

    千次阅读 2018-03-10 21:46:27
    1、创建command2、执行command3、request cache4、短路器,如果打开了,fallback降级机制1、fallback降级机制 (1)hystrix调用各种接口,或者访问外部依赖,mysql,redis,zookeeper,kafka,等等,如果出现了任何...


    1、创建command
    2、执行command
    3、request cache
    4、短路器,如果打开了,fallback降级机制


    1、fallback降级机制


    (1)hystrix调用各种接口,或者访问外部依赖,mysql,redis,zookeeper,kafka,等等,如果出现了任何异常的情况
    比如说报错了,访问mysql报错,redis报错,zookeeper报错,kafka报错,error


    (2)对每个外部依赖,无论是服务接口,中间件,资源隔离,对外部依赖只能用一定量的资源去访问,线程池/信号量,如果资源池已满,reject


    (3)访问外部依赖的时候,访问时间过长,可能就会导致超时,报一个TimeoutException异常,timeout


    上述三种情况,都是我们说的异常情况,对外部依赖的东西访问的时候出现了异常,发送异常事件到短路器中去进行统计


    (4)如果短路器发现异常事件的占比达到了一定的比例,直接开启短路,circuit breaker


    上述四种情况,都会去调用fallback降级机制




    fallback,降级机制,你之前都是必须去调用外部的依赖接口,或者从mysql中去查询数据的,但是为了避免说可能外部依赖会有故障


    比如,你可以再内存中维护一个ehcache,作为一个纯内存的基于LRU自动清理的缓存,数据也可以放入缓存内


    如果说外部依赖有异常,fallback这里,直接尝试从ehcache中获取数据


    比如说,本来你是从mysql,redis,或者其他任何地方去获取数据的,获取调用其他服务的接口的,结果人家故障了,人家挂了,fallback,可以返回一个默认值


    两种最经典的降级机制:纯内存数据,默认值


    run()抛出异常,超时,线程池或信号量满了,或短路了,都会调用fallback机制


    给大家举个例子,比如说我们现在有个商品数据,brandId,品牌,一般来说,假设,正常的逻辑,拿到了一个商品数据以后,用brandId再调用一次请求,到其他的服务去获取品牌的最新名称


    假如说,那个品牌服务挂掉了,那么我们可以尝试本地内存中,会保留一份时间比较过期的一份品牌数据,有些品牌没有,有些品牌的名称过期了,Nike++,Nike


    调用品牌服务失败了,fallback降级就从本地内存中获取一份过期的数据,先凑合着用着






    2、fallback.isolation.semaphore.maxConcurrentRequests


    这个参数设置了HystrixCommand.getFallback()最大允许的并发请求数量,默认值是10,也是通过semaphore信号量的机制去限流


    如果超出了这个最大值,那么直接被reject


    HystrixCommandProperties.Setter()
       .withFallbackIsolationSemaphoreMaxConcurrentRequests(int value)
       
       
       
       
       
       HystrixCommand实现getFallback方法


    public class GetBrandNameCommand extends HystrixCommand<String> {

    private Long brandId;

    public GetBrandNameCommand(Long brandId) {
    super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("BrandInfoService"))
    .andCommandKey(HystrixCommandKey.Factory.asKey("GetBrandNameCommand"))
    .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("GetBrandInfoPool"))
    .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
    .withCoreSize(15)//设置线程池大小
    .withQueueSizeRejectionThreshold(10))//设置等待队列大小
    .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
    .withFallbackIsolationSemaphoreMaxConcurrentRequests(15))//设置最大允许的降级并发请求数量,默认值是10,也是通过semaphore信号量的机制去限流
    );  
    this.brandId = brandId;
    }

    @Override
    protected String run() throws Exception {
    // 调用一个品牌服务的接口
    // 如果调用失败了,报错了,那么就会去调用fallback降级机制
    throw new Exception();
    }

    @Override
    protected String getFallback() {
    System.out.println("从本地缓存获取过期的品牌数据,brandId=" + brandId);  
    return BrandCache.getBrandName(brandId);
    }


    }



    HystrixObservableCommand,是实现resumeWithFallback方法




       
       
       
       


    展开全文
  • 短路器,如果打开了,fallback降级机制 1 fallback降级机制 Hystrix调用各种接口,或者访问外部依赖,MySQL,Redis,ZooKeeper,Kafka等,出现任何异常的情况,比如访问报错 对每个外部依赖,无论是服务接口,...

    执行流程

    1. 创建command
    2. 执行command
    3. request cache
    4. 短路器,如果打开了,fallback降级机制

    1 fallback降级机制

    • Hystrix调用各种接口,或者访问外部依赖,MySQL,Redis,ZooKeeper,Kafka等,出现任何异常的情况,比如访问报错
    • 对每个外部依赖,无论是服务接口,中间件,资源隔离,对外部依赖只能用一定量的资源去访问,线程池/信号量等资源池已满
    • reject访问外部依赖的时候,访问时间过长,可能就会导致超时,报一个TimeoutException异常,timeout
    • 对外部依赖的东西访问的时候出现了异常,发送异常事件到短路器中去进行统计
      如果短路器发现异常事件的占比达到了一定比例,直接开启短路(circuit breaker)

    上述四种情况,都会去调用fallback降级机制
    fallback,你之前都是必须去调用外部的依赖接口,或者从MySQL中去查询数据的,但是为了避免说可能外部依赖会有故障

    2 实现方案

    2.1 纯内存数据

    可以在内存中维护一个ECache,作为基于LRU自动清理的纯内存缓存,数据也可放入缓存
    如果说外部依赖有异常,fallback这里,直接尝试从ECache中获取数据

    2.2 默认值

    本来你是从mysql,redis,或者其他任何地方去获取数据的,获取调用其他服务的接口的,结果人家故障了,人家挂了,fallback,可以返回一个默认值

    run()抛出异常,超时,线程池或信号量满了,或短路了,都会调用fallback机制

    案例

    现在有个商品数据,brandId,品牌,假设拿到了一个商品数据以后,用brandId再调用一次请求,到其他的服务去获取品牌的最新名称

    假如那个品牌服务挂掉了,那么我们可以尝试本地内存中,会保留一份时间比较过期的一份品牌数据,有些品牌没有,有些品牌的名称过期了,调用品牌服务失败了,fallback降级就从本地内存中获取一份过期的数据,先凑合着用着

    public class CommandHelloFailure extends HystrixCommand<String> {
    
        private final String name;
    
        public CommandHelloFailure(String name) {
            super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
            this.name = name;
        }
    
        @Override
        protected String run() {
            throw new RuntimeException("this command always fails");
        }
    
        @Override
        protected String getFallback() {
            return "Hello Failure " + name + "!";
        }
    
    }
    
    @Test
    public void testSynchronous() {
        assertEquals("Hello Failure World!", new CommandHelloFailure("World").execute());
    }
    

    HystrixObservableCommand,是实现resumeWithFallback方法

    2、fallback.isolation.semaphore.maxConcurrentRequests

    这个参数设置了HystrixCommand.getFallback()最大允许的并发请求数量,默认值是10,也是通过semaphore信号量的机制去限流

    如果超出了这个最大值,那么直接被reject

    HystrixCommandProperties.Setter()
       .withFallbackIsolationSemaphoreMaxConcurrentRequests(int value)
    
    
    展开全文
  • 基于本地缓存的 fallback 降级机制 Hystrix 出现以下四种情况,都会去调用 fallback 降级机制: 断路器处于打开的状态。 资源池已满(线程池+队列 / 信号量)。 Hystrix 调用各种接口,或者访问外部依赖,比如 ...
  • Hystrix面试 - 基于本地缓存的 fallback 降级机制 Hystrix 出现以下四种情况,都会去调用 fallback 降级机制: 断路器处于打开的状态。 资源池已满(线程池+队列 / 信号量)。 Hystrix 调用各种接口,或者访问...
  • 7.1 四种情况fallback降级机制 (1)[error] Hystrix调用各种接口,或者访问外部依赖,mysql,redis,zookeeper,kafka,等等,如果出现了任何异常的情况 比如说报错了,访问mysql报错,redis报错,zookeeper报错...
  • 上篇文章详细介绍了Hystrix的fallback降级逻辑,并且深入分析了其源码实现:`getFallbackOrThrowException()`方法,但我在文末留下了一个小问题:Hystrix中哪些情况会触发它的降级逻辑呢? 带着这个疑问开始这篇...
  • 1.介绍stubbed fallback 残缺的降级 用请求中的部分数据拼装成结果,然后再填充一些默认值,返回 比如说你发起了一个请求,然后请求中可能本身就附带了一些信息,如果主请求失败了,走到降级逻辑。在降级逻辑里面,...
  • 发现产生了服务降级,但是没有详细的错误日志打印 我们可以使用fallbackFactory打印feign调用的异常 === feign调用异常处理 1、产生fallbackFactory的组件 2、在FeignClient注解中通过fallbackFactory...
  • SpringCloud+Feign+Hystrix统一FallbackFactory降级处理

    千次阅读 热门讨论 2021-01-20 18:01:12
    SpringCloud+Feign+Hystrix统一FallbackFactory降级处理概述说明前提源码分析扩展、统一FallbackFactory其他说明结果 概述说明 当我们使用Spring cloud的时候,基本都是会用到Feign、Hystrix相关技术。每一个接口类...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,736
精华内容 4,694
关键字:

fallback降级