zoukankan      html  css  js  c++  java
  • Feign性能优化注意事项--超时

     

    Caused by: java.lang.IllegalStateException: PathVariable annotation was empty on param 1.
        at feign.Util.checkState(Util.java:128) ~[feign-core-9.5.0.jar:na]
        at org.springframework.cloud.netflix.feign.annotation.PathVariableParameterProcessor.processArgument(PathVariableParameterProcessor.java:51) ~[spring-cloud-netflix-core-1.4.4.RELEASE.jar:1.4.4.RELEASE]
        at org.springframework.cloud.netflix.feign.support.SpringMvcContract.processAnnotationsOnParameter(SpringMvcContract.java:238) ~[spring-cloud-netflix-core-1.4.4.RELEASE.jar:1.4.4.RELEASE]
        at feign.Contract$BaseContract.parseAndValidateMetadata(Contract.java:107) ~[feign-core-9.5.0.jar:na]
        at org.springframework.cloud.netflix.feign.support.SpringMvcContract.parseAndValidateMetadata(SpringMvcContract.java:133) ~[spring-cloud-netflix-core-1.4.4.RELEASE.jar:1.4.4.RELEASE]
        at feign.Contract$BaseContract.parseAndValidatateMetadata(Contract.java:64) ~[feign-core-9.5.0.jar:na]
        at feign.ReflectiveFeign$ParseHandlersByName.apply(ReflectiveFeign.java:146) ~[feign-core-9.5.0.jar:na]
        at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:53) ~[feign-core-9.5.0.jar:na]
        at feign.Feign$Builder.target(Feign.java:218) ~[feign-core-9.5.0.jar:na]
        at org.springframework.cloud.netflix.feign.HystrixTargeter.target(HystrixTargeter.java:39) ~[spring-cloud-netflix-core-1.4.4.RELEASE.jar:1.4.4.RELEASE]
        at org.springframework.cloud.netflix.feign.FeignClientFactoryBean.loadBalance(FeignClientFactoryBean.java:211) ~[spring-cloud-netflix-core-1.4.4.RELEASE.jar:1.4.4.RELEASE]
        at org.springframework.cloud.netflix.feign.FeignClientFactoryBean.getObject(FeignClientFactoryBean.java:232) ~[spring-cloud-netflix-core-1.4.4.RELEASE.jar:1.4.4.RELEASE]
        at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:178) ~[spring-beans-4.3.17.RELEASE.jar:4.3.17.RELEASE]
        ... 68 common frames omitted

    使用Feign的时候,如果参数中带有

    @PathVariable形式的参数,则要用value=""标明对应的参数,否则会抛出IllegalStateException异常


    @PutMapping("/disuseable/{sn}")
    ApiResponse disUseAble(@PathVariable String sn); // wrong

    -->
    @PutMapping("/disuseable/{sn}")
    ApiResponse disUseAble(@PathVariable(value="sn") String sn); // right

    -->
    @PutMapping("/disuseable/{sn}")
    ApiResponse disUseAble(@PathVariable("sn") String sn); // right





    一、FeignClient注解

      FeignClient注解被@Target(ElementType.TYPE)修饰,表示FeignClient注解的作用目标在接口上

    @FeignClient(name = "github-client", url = "https://api.github.com", configuration = GitHubExampleConfig.class)
    public interface GitHubClient {
        @RequestMapping(value = "/search/repositories", method = RequestMethod.GET)
        String searchRepo(@RequestParam("q") String queryStr);
    }

    声明接口之后,在代码中通过@Resource注入之后即可使用。@FeignClient标签的常用属性如下:

    • name:指定FeignClient的名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现
    • url: url一般用于调试,可以手动指定@FeignClient调用的地址
    • decode404:当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
    • configuration: Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
    • fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
    • fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码

    path: 定义当前FeignClient的统一前缀

    @FeignClient(name = "github-client",
            url = "https://api.github.com",
            configuration = GitHubExampleConfig.class,
            fallback = GitHubClient.DefaultFallback.class)
    public interface GitHubClient {
        @RequestMapping(value = "/search/repositories", method = RequestMethod.GET)
        String searchRepo(@RequestParam("q") String queryStr);
     
        /**
         * 容错处理类,当调用失败时,简单返回空字符串
         */
        @Component
        public class DefaultFallback implements GitHubClient {
            @Override
            public String searchRepo(@RequestParam("q") String queryStr) {
                return "";
            }
        }
    }

    在使用fallback属性时,需要使用@Component注解,保证fallback类被Spring容器扫描到,GitHubExampleConfig内容如下:

    @Configuration
    public class GitHubExampleConfig {
        @Bean
        Logger.Level feignLoggerLevel() {
            return Logger.Level.FULL;
        }
    }

    在使用FeignClient时,Spring会按name创建不同的ApplicationContext,通过不同的Context来隔离FeignClient的配置信息,在使用配置类时,不能把配置类放到Spring App Component scan的路径下,否则,配置类会对所有FeignClient生效.

    二、Feign Client 和@RequestMapping
    当前工程中有和Feign Client中一样的Endpoint时,Feign Client的类上不能用@RequestMapping注解否则,当前工程该endpoint http请求且使用accpet时会报404
    Controller:
    @RestController
    @RequestMapping("/v1/card")
    public class IndexApi {
     
        @PostMapping("balance")
        @ResponseBody
        public Info index() {
            Info.Builder builder = new Info.Builder();
            builder.withDetail("x", 2);
            builder.withDetail("y", 2);
            return builder.build();
        }
    }


    Feign Client
    @FeignClient(
            name = "card",
            url = "http://localhost:7913",
            fallback = CardFeignClientFallback.class,
            configuration = FeignClientConfiguration.class
    )
    @RequestMapping(value = "/v1/card")
    public interface CardFeignClient {
     
        @RequestMapping(value = "/balance", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
        Info info();
     
    }

    if @RequestMapping is used on class, when invoke http /v1/card/balance, like this :

    如果 @RequestMapping注解被用在FeignClient类上,当像如下代码请求/v1/card/balance时,注意有Accept header:

    Content-Type:application/json
    Accept:application/json
     
    POST http://localhost:7913/v1/card/balance

    那么会返回 404。

    如果不包含Accept header时请求,则是OK:

    Content-Type:application/json
    POST http://localhost:7913/v1/card/balance

    或者像下面不在Feign Client上使用@RequestMapping注解,请求也是ok,无论是否包含Accept:

    @FeignClient(
            name = "card",
            url = "http://localhost:7913",
            fallback = CardFeignClientFallback.class,
            configuration = FeignClientConfiguration.class
    )
     
    public interface CardFeignClient {
     
        @RequestMapping(value = "/v1/card/balance", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
        Info info();
     
    }

    三、Feign请求超时问题

    Hystrix默认的超时时间是1秒,如果超过这个时间尚未响应,将会进入fallback代码。而首次请求往往会比较慢(因为Spring的懒加载机制,要实例化一些类),这个响应时间可能就大于1秒了
    解决方案有三种,以feign为例。
    方法一
    hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
    该配置是让Hystrix的超时时间改为5秒
    方法二
    hystrix.command.default.execution.timeout.enabled: false
    该配置,用于禁用Hystrix的超时时间
    方法三
    feign.hystrix.enabled: false
    该配置,用于索性禁用feign的hystrix。该做法除非一些特殊场景,不推荐使用。
  • 相关阅读:
    Java 泛型 泛型的约束与局限性
    Java 泛型 泛型方法
    Java 泛型 泛型数组
    Java 泛型 协变性、逆变性
    Java 泛型 协变式覆盖和泛型重载
    Java 泛型 泛型代码和虚拟机
    Insertion Sort List
    Remove Duplicates from Sorted List II
    String to Integer (atoi)
    SpringMvc源码入门
  • 原文地址:https://www.cnblogs.com/softidea/p/10269436.html
Copyright © 2011-2022 走看看