zoukankan      html  css  js  c++  java
  • Hystrix熔断的方法级别(自定义commonKey)

    一、Hystrix的Feign熔断的粒度

    Feign可以直接去集成Hystrix熔断,那么默认的熔断粒度是多大呢?或者说,当serviceA调用serviceB#method1(param)时,如果出现超时导致熔断后,serviceA还能不能调用serviceB#method2(param)呢?

    我做了一个模拟测试,当serviceA调用serviceB#method1(param)时,报错信息如下:

    com.netflix.hystrix.exception.HystrixRuntimeException: serviceB#method1(param) short-circuited and no fallback available.

    at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:819)

    当serviceA调用serviceB#method2(param)时,请求和返回都是正常的。

    结论:Hystrix熔断的粒度是方法层面的。

    根据上面的报错的AbstractCommand.java:819跟进到源码中:

         toEmit = new HystrixRuntimeException(failureType, _cmd.getClass(), getLogMessagePrefix() + " " + message + " and no fallback available.", e, fe);
    
        //serviceB#method1(param)的来源   
        protected String getLogMessagePrefix() {
            return getCommandKey().name();
        }
     
        //
        public HystrixCommandKey getCommandKey() {
            return commandKey;
        }
        //group默认是服务名称
        this.commandGroup = initGroupKey(group);
        //key默认是feignclient的类名#method(参数名称)
        this.commandKey = initCommandKey(key, getClass());
    
        //
        private static HystrixCommandKey initCommandKey(final HystrixCommandKey fromConstructor, Class<?> clazz) {
            if (fromConstructor == null || fromConstructor.name().trim().equals("")) {
                final String keyName = getDefaultNameFromClass(clazz);
                return HystrixCommandKey.Factory.asKey(keyName);
            } else {
                return fromConstructor;
            }
        }

    也就是说熔断的粒度是FeignClient类下的方法层面。 

    二、自定义熔断的范围

    Feign-灵活的使用Hystrix熔断(自定义CommandKey)

    但是配置时,却不是很灵活,只是支持default类名#方法名()的配置。这就不能对类或者一组方法进行统一的配置。

    源码改造:

    @Configuration
    public class MyHystrixFeign {
    
        @Bean
        @Scope("prototype")
        @ConditionalOnProperty(name = "feign.hystrix.enabled")
        public Feign.Builder feignHystrixBuilder() {
            return HystrixFeign.builder().setterFactory(new MyDefault());
        }
    
        /**
         * 修改源码{@link HystrixFeign.Builder#setterFactory}
         */
        final class MyDefault implements SetterFactory {
    
            @Override
            public HystrixCommand.Setter create(Target<?> target, Method method) {
           
                String groupKey = target.name();
                String commandKey = Feign.configKey(target.type(), method);
                //
                if ("TestDemoApi1".equals(target.type().getSimpleName())) {
                    return HystrixCommand.Setter
                            .withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
                            .andCommandKey(HystrixCommandKey.Factory.asKey("TestDemoApi1"))
                            .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(commandKey));
                }
                return HystrixCommand.Setter
                        .withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
                        .andCommandKey(HystrixCommandKey.Factory.asKey(commandKey));
            }
        }
    
    }

    项目启动后,会遍历@Feign注解类中的每一个方法调用create生成Hystrix的配置key,也可以是线程池的key。
    源码位置:feign.hystrix.HystrixInvocationHandler#toSetters如下图所示。

      /**
       * Process all methods in the target so that appropriate setters are created.
       * 为每一个方法增加熔断的配置(可以在代码中配置,也可以在yml中进行配置)。
       */
      static Map<Method, Setter> toSetters(SetterFactory setterFactory, Target<?> target,
                                           Set<Method> methods) {
        Map<Method, Setter> result = new LinkedHashMap<Method, Setter>();
        for (Method method : methods) {
          method.setAccessible(true);
          //扩展的是这个方法(由用户自己定义配置)。
          result.put(method, setterFactory.create(target, method));
        }
        return result;
      }

    yml的配置:

    feign:
      # Dalston SR1(待定)之后的版本默认关闭hystrix对feign的支持,如果想要使用fallback功能这里必须启用。
      hystrix:
        enabled: true
    #
    #
    #hystrix:
    #  command:
    #    default:
    #      execution:
    #        isolation:
    #          thread:
    #            timeoutInMilliseconds: 100000  # 调用者执行的超时时间默认是1s
    #  threadpool:
    #    default:
    #      coreSize: 1 #核心线程数
    #      maximumSize: 1 # 最大线程数
    #      maxQueueSize: 0 # 不使用队列
    #
    
    ## Feign仅仅支持方法级别和default级别
    hystrix:
      command:
        TestDemoApi1:   ## 支持类级别
         execution:
          isolation:
           thread:
            timeoutInMilliseconds: 4000  # 调用者执行的超时时间默认是1s

    注:默认情况下,Feign-Hystrix会使用服务名作为CommandGroup,使用类名#方法名作为CommandKey。

    而在yml配置:全局配置是default的配置,而实例配置为commandKey配置。

    更多的配置,可以参考Hystrix(2)— 相关配置



    参考:https://www.jianshu.com/p/58f6e180999f

  • 相关阅读:
    Visual Studio 2010 VS IDE 编辑界面出现绿色的点 去掉绿色的空格点
    C# TreeView 拖拽节点到另一个容器Panel中简单实现
    C#GDI+ 绘制线段(实线或虚线)、矩形、字符串、圆、椭圆
    MySql.Data.dll官网下载
    线性插值法
    C#俄罗斯方块小游戏程序设计与简单实现
    C#二分查找算法设计实现
    C#获取一个数组中的最大值、最小值、平均值
    国内外工业互联网平台介绍【揭晓】工业互联网平台浪潮来临,最全的国内外平台都长的啥样!
    Windows 环境Oracle客户端下载安装
  • 原文地址:https://www.cnblogs.com/duanxz/p/14597894.html
Copyright © 2011-2022 走看看