• SpringCloud对服务内某个client进行单独配置


    问题

    我们的微服务项目用的是springCloud,某个微服务接口因为数据处理量大,出现了接口超时的情况,我们需要单独修改这一个feignClient的超时时间。


    解决过程

    一开始项目只是在application文件里面进行了全局的简单配置,搜索了一下,添加了一个配置类写在@FeignClient注解的参数里

    @Configuration
    public class MyFeignConfig {
    
        @Bean
        Request.Options feignOptions(){
            return new Request.Options(20000, TimeUnit.MILLISECONDS,20000, TimeUnit.MILLISECONDS,false);
        }
    
    }
    
    @FeignClient(value = "app", configuration = {FeignClientConfig.class,MyFeignConfig.class}, fallbackFactory = ApprovalClientFallBack.class)
    public interface AppClient {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    测试后发现并没有解决问题,还是在超时,于是点进报错的源码debug了一下

    image.png
    image.png

    发现这个option并不是我上面配置类配置的值
    一路往上点,找到option被写入进去的地方FeignClientFactoryBean#configureUsingConfiguration

    image.png

    可以看到这里的option是通过context拿到的,接着点进去
    image.png

    这个类就是传递配置的地方,一个name有一个配置列表

    image.png

    这里的configuration是Autowired注入进去的,但是最后option却没有拿到,于是考虑难道是配置没注入进去?
    找到@FeignClient的参数注册的代码FeignClientsRegistrar#registerFeignClients

    image.png

    注意这里的registerClientConfiguration和getClientName方法,getClientName拿到每个FeignClient的name,然后把configuration注入到那个name下。问题出现了
    A服务有很多个FeignClient,我只需要对其中的一个进行特殊配置,但是所有的FeignClient注解的value值都是一样的,这里获得的name也就是一样的,那么后面注册的configuration就会把前面的覆盖掉,导致我们自己写的配置失效
    点进getClientName方法

    image.png

    看代码,只要FeignClient注解的contextId有值,就会直接取contextId而不取value或者name,那么给需要特殊配置的Client写上contextId是不是配置就生效了

    
    @FeignClient(value = "app",contextId = "appSpecial",  configuration = {FeignClientConfig.class,MyFeignConfig.class}, fallbackFactory = ApprovalClientFallBack.class)
    public interface AppClient {}
    
    • 1
    • 2
    • 3

    测试后发现所有服务的超时时间都变成20000了
    这里有个坑要注意,配置类不能有@Configuration注解,否则会被全局扫描到,变成了全局配置。去掉@Configuration后测试,问题解决。


    问题解决

    综上
    因为配置文件配置的优先级高于配置类,所以删掉application文件里的配置,采用配置类配置。
    在项目统一的FeignClientConfig里加上统一的超时时间配置

    @Configuration
    public class FeignClientConfig {
    
        /**
         * 配置header
         */
        @Bean
        public RequestInterceptor requestInterceptor() {
            return new FeignClientInterceptor();
        }
        /**
         * 配置统一的超时时间
         */
        @Bean
        Request.Options feignOptions(){
            return new Request.Options(10000, TimeUnit.MILLISECONDS,10000, TimeUnit.MILLISECONDS,false);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    对需要单独配置的client添加自定义配置

    public class MyFeignConfig {
        @Bean
        Request.Options feignOptions(){
            return new Request.Options(20000, TimeUnit.MILLISECONDS,20000, TimeUnit.MILLISECONDS,false);
        }
    
    }
    
    @FeignClient(value = "app", contextId = "appSpecial", configuration = {FeignClientConfig.class,
            MyFeignConfig.class}, fallbackFactory = ClientFallBack.class)
    public interface AppClient {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    NIO基础-ByteBuffer,Channel
    Fritzing软件绘制Arduino面包板接线图传感器模块库文件216
    R语言ggplot2可视化:可视化多行文本内容并添加箭头、指定文本可视化内容右对齐(right alignment)
    “Python+”集成技术高光谱遥感数据处理与机器学习深度应用
    用控件当画笔获得bitmap代码记录
    110. 平衡二叉树
    程序员是做什么的?怎么成为程序员?
    超详细的Asp.net使用SSL双向认证,一篇就够了
    软件测试(一)概念
    如何阅读一本书(上)
  • 原文地址:https://blog.csdn.net/weixin_48356746/article/details/133909069