feignclient設置hystrix參數

feign默認集成了hystrix,那麼問題來了,如何像hystrix command那樣設置每一個方法的hystrix屬性呢。java

實例

@FeignClient("product")
public interface RemoteProductService {

    @RequestMapping(method = RequestMethod.GET,value = "/product/{productId}")
    public Product getProduct(@PathVariable(value = "productId")  int productId);
}

FeignClientsConfiguration

spring-cloud-netflix-core-1.2.6.RELEASE-sources.jar!/org/springframework/cloud/netflix/feign/FeignClientsConfiguration.javaspring

@Configuration
    @ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class })
    protected static class HystrixFeignConfiguration {
        @Bean
        @Scope("prototype")
        @ConditionalOnMissingBean
        @ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = true)
        public Feign.Builder feignHystrixBuilder() {
            return HystrixFeign.builder();
        }
    }

HystrixFeign

feign-hystrix-9.3.1-sources.jar!/feign/hystrix/HystrixFeign.java微信

private SetterFactory setterFactory = new SetterFactory.Default();

SetterFactory

feign-hystrix-9.3.1-sources.jar!/feign/hystrix/SetterFactory.javaapp

public interface SetterFactory {

  /**
   * Returns a hystrix setter appropriate for the given target and method
   */
  HystrixCommand.Setter create(Target<?> target, Method method);

  /**
   * Default behavior is to derive the group key from {@link Target#name()} and the command key from
   * {@link Feign#configKey(Class, Method)}.
   */
  final class Default implements SetterFactory {

    @Override
    public HystrixCommand.Setter create(Target<?> target, Method method) {
      String groupKey = target.name();
      String commandKey = Feign.configKey(target.type(), method);
      return HystrixCommand.Setter
          .withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
          .andCommandKey(HystrixCommandKey.Factory.asKey(commandKey));
    }
  }
}

groupKey,這裏爲product,即@FeignClient("product")中的值。ide

Feign.configKey

feign-core-9.3.1-sources.jar!/feign/Feign.javaui

public static String configKey(Class targetType, Method method) {
    StringBuilder builder = new StringBuilder();
    builder.append(targetType.getSimpleName());
    builder.append('#').append(method.getName()).append('(');
    for (Type param : method.getGenericParameterTypes()) {
      param = Types.resolve(targetType, targetType, param);
      builder.append(Types.getRawType(param).getSimpleName()).append(',');
    }
    if (method.getParameterTypes().length > 0) {
      builder.deleteCharAt(builder.length() - 1);
    }
    return builder.append(')').toString();
  }

commandKey的構造,這裏組裝了類、方法名、參數,好比本文的實例,commandKey=RemoteProductService#getProduct(int)spa

配置文件指定

hystrix:
    command:
        "RemoteProductService#getProduct(int)":
            execution:
                isolation:
                    thread:
                        timeoutInMilliseconds: 500

Java中指定

@Bean
    public Feign.Builder feignHystrixBuilder() {
        return HystrixFeign.builder().setterFactory(new SetterFactory() {
            @Override
            public HystrixCommand.Setter create(Target<?> target, Method method) {
                return HystrixCommand.Setter
                        .withGroupKey(HystrixCommandGroupKey.Factory.asKey(RemoteProductService.class.getSimpleName()))// 控制 RemoteProductService 下,全部方法的Hystrix Configuration
                        .andCommandPropertiesDefaults(
                                HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(10000) // 超時配置
                        );
            }
        });
    }

小結

論靈活程度,仍是配置文件靈活一點,惟一的工做量就是根據規則構造commandKey,而後就能夠進行相關配置了。prototype


想獲取最新內容,請關注微信公衆號code

圖片描述