真实案例:Feign切换client到okhttp无法生效,被老大骂的有点慌!

沙海 2021年8月28日09:10:37Java评论113字数 5010阅读16分42秒阅读模式
摘要

真实案例:Feign切换client到okhttp无法生效,被老大骂的有点慌! 点击关注? Java面试那些事儿

真实案例:Feign切换client到okhttp无法生效,被老大骂的有点慌!

点击关注? Java面试那些事儿 文章源自JAVA秀-https://www.javaxiu.com/42858.html

收录于话题#Java面试那些事儿,359个文章源自JAVA秀-https://www.javaxiu.com/42858.html

大家好,我是D哥点击关注世界公众号,Java面试资料都在这里

文章源自JAVA秀-https://www.javaxiu.com/42858.html

来源:https://www.cnblogs.com/mufeng3421/p/11442412.html文章源自JAVA秀-https://www.javaxiu.com/42858.html

文章源自JAVA秀-https://www.javaxiu.com/42858.html

提示:如果只看如何解决问题,请看文章的末尾如何解决这个问题文章源自JAVA秀-https://www.javaxiu.com/42858.html

文章源自JAVA秀-https://www.javaxiu.com/42858.html

# 场景描述

文章源自JAVA秀-https://www.javaxiu.com/42858.html

最近项目中使用了feign当做http请求工具来使用、相对于httpclient、resttemplate来说,fegin用起来方便很多。然后项目有httptrace的需求,需要输出请求日志。所以就开启了feign自己的日志,发现它自带的日志是debug级别才能打印。而且是逐行打印的,看日志非常的不方便。所以需要输出json格式的日志最好。文章源自JAVA秀-https://www.javaxiu.com/42858.html

# 解决步骤

引入feign依赖

    <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${自行选择适合项目的版本}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>
    文章源自JAVA秀-https://www.javaxiu.com/42858.html

    这里使用了spring-cloud-openfeing来避免自己手工实现feign的注入,用法上和feign一样文章源自JAVA秀-https://www.javaxiu.com/42858.html

    配置feign

    在入口类上添加 @EnableFeignClients 注解文章源自JAVA秀-https://www.javaxiu.com/42858.html

      @SpringBootApplication@EnableFeignClientspublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}
      文章源自JAVA秀-https://www.javaxiu.com/42858.html

      使用feing自己的Contract,方便使用feign自己的注解来声明http接口。这里使用了一个配置类文章源自JAVA秀-https://www.javaxiu.com/42858.html

        @Configurationpublic class FeignConfig { @Bean public Contract feignContract() { return new feign.Contract.Default(); }}
        文章源自JAVA秀-https://www.javaxiu.com/42858.html

        声明接口

        文章源自JAVA秀-https://www.javaxiu.com/42858.html

        只需要声明一个带有@FeignClient注解的接口,就声明好了一个Feign的http请求接口文章源自JAVA秀-https://www.javaxiu.com/42858.html

          @FeignClient(name = "accessPlatform", url = "${url.access-platform}")public interface AccessPlatformFeignClient { @RequestLine("GET /access-platform/resource") List<AccessResource> queryResourceList(@QueryMap Map<String, Object> query);}
          文章源自JAVA秀-https://www.javaxiu.com/42858.html

          文章源自JAVA秀-https://www.javaxiu.com/42858.html

          # 切换Feign的客户端为OkHttp文章源自JAVA秀-https://www.javaxiu.com/42858.html

          由于feign自带的http客户端实现是HttpURLConnection,没有连接池功能,可配置能力也比较差,因此我们使用okhttp作为底层的http客户端的具体实现。文章源自JAVA秀-https://www.javaxiu.com/42858.html

          引入okhttp的依赖

             <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> <version>${feign-okhttp.version}</version></dependency>
            文章源自JAVA秀-https://www.javaxiu.com/42858.html

            修改之前的FeignConfig配置类

            问题就出在这里、不过先不急,我们继续文章源自JAVA秀-https://www.javaxiu.com/42858.html

              @Configuration@ConditionalOnClass(Feign.class)@AutoConfigureBefore(FeignAutoConfiguration.class)public class FeignConfig { // 注入feignContract @Bean public Contract feignContract() { return new feign.Contract.Default(); } // 注入自定义的okHttpClient @Bean public okhttp3.OkHttpClient okHttpClient(){ return new okhttp3.OkHttpClient.Builder() .readTimeout(60, TimeUnit.SECONDS) .connectTimeout(60, TimeUnit.SECONDS)  .writeTimeout(120, TimeUnit.SECONDS)  .connectionPool(new ConnectionPool()) .build(); }}
              文章源自JAVA秀-https://www.javaxiu.com/42858.html

              开启okhttp作为feign的客户端文章源自JAVA秀-https://www.javaxiu.com/42858.html

                # application.ymlfeign: okhttp: enabled: true
                文章源自JAVA秀-https://www.javaxiu.com/42858.html

                一切完美、网上的许多博客也都是这么写的。然后它们告诉你已经配置完了?呵呵,你们到底自己试过没有??文章源自JAVA秀-https://www.javaxiu.com/42858.html

                试着请求一下

                当然这里出问题了,发出的请求并非来自okhttp,还是默认的JDK的HttpURLConnection,问题出在哪里呢?接着看文章源自JAVA秀-https://www.javaxiu.com/42858.html

                # 找出问题所在

                我怀疑是feing在注入配置的时候,根本就没有运行关于okhttp的配置文章源自JAVA秀-https://www.javaxiu.com/42858.html

                查看服务启动时feign配置过程

                1.将服务根日志级别调整为debug级别文章源自JAVA秀-https://www.javaxiu.com/42858.html

                  logging: level: root: debug
                  文章源自JAVA秀-https://www.javaxiu.com/42858.html

                  2.启动服务、查看控制台输出真实案例:Feign切换client到okhttp无法生效,被老大骂的有点慌!看到没,okhttp的配置不符合配置运行条件。文章源自JAVA秀-https://www.javaxiu.com/42858.html

                  文章源自JAVA秀-https://www.javaxiu.com/42858.html

                  3.查询 FeignAutoConfiguration 这个配置类的细节文章源自JAVA秀-https://www.javaxiu.com/42858.html

                    @Configuration@ConditionalOnClass({Feign.class})@EnableConfigurationProperties({FeignClientProperties.class, FeignHttpClientProperties.class})publicclassFeignAutoConfiguration{// .....其他的配置@Configuration@ConditionalOnClass({OkHttpClient.class})@ConditionalOnMissingClass({"com.netflix.loadbalancer.ILoadBalancer"})@ConditionalOnMissingBean({okhttp3.OkHttpClient.class})@ConditionalOnProperty({"feign.okhttp.enabled"})protected static classOkHttpFeignConfiguration{// ...okhttp的配置 }// .....其他的配置}
                    文章源自JAVA秀-https://www.javaxiu.com/42858.html

                    就是这个自动配置类搞的鬼、当我看到 @ConditionalOnMissingBean({okhttp3.OkHttpClient.class}) 这个注解时,我就明白了。文章源自JAVA秀-https://www.javaxiu.com/42858.html

                    翻成白话就是,只有当容器中没有OkHttpClient的实例时。他才会运行。如果在 FeignAutoConfiguration之前注入了我们自己定义的OkHttpClient实例,那不好意思,我不干了?无不注入。文章源自JAVA秀-https://www.javaxiu.com/42858.html

                    # 解决问题

                    既然自动配置不干,那我们自己动手干。拷贝 FeignAutoConfiguration 配置类中的配置过程,粘贴在FeignConfig配置类中手动注入feign的client。Ok!完美解决。文章源自JAVA秀-https://www.javaxiu.com/42858.html

                      @Configuration@ConditionalOnClass(Feign.class)@AutoConfigureAfter(FeignAutoConfiguration.class)publicclassFeignConfig{// private okhttp3.OkHttpClient okHttpClient;@Beanpublic Contract feignContract() {return new feign.Contract.Default(); }@Bean@ConditionalOnMissingBean({Client.class})public Client feignClient(okhttp3.OkHttpClient client) {return new feign.okhttp.OkHttpClient(client); }@Bean@ConditionalOnMissingBean({ConnectionPool.class})public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties, OkHttpClientConnectionPoolFactory connectionPoolFactory) { Integer maxTotalConnections = httpClientProperties.getMaxConnections();Long timeToLive = httpClientProperties.getTimeToLive(); TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit); }@Beanpublic OkHttpClient client(OkHttpClientFactory httpClientFactory, ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) {Boolean followRedirects = httpClientProperties.isFollowRedirects(); Integer connectTimeout = httpClientProperties.getConnectionTimeout();Boolean disableSslValidation = httpClientProperties.isDisableSslValidation();return httpClientFactory.createBuilder(disableSslValidation) .connectTimeout((long)connectTimeout, TimeUnit.MILLISECONDS) .followRedirects(followRedirects) .connectionPool(connectionPool) .addInterceptor(new OkHttpLogInterceptor()) // 自定义请求日志拦截器 .build(); }}
                      文章源自JAVA秀-https://www.javaxiu.com/42858.html

                      # 小结

                      如果你没有耐心看完所有的过程的话。就记住一句话:用自己手动注入Feign的Client实现,来代替 Feign的自动配置所做的过程就好了。具体的配置请看第5点。文章源自JAVA秀-https://www.javaxiu.com/42858.html

                      文章源自JAVA秀-https://www.javaxiu.com/42858.html

                      技术交流群D哥也了一个技术群,主要针对一些新的技术和开源项目值不值得去研究和IDEA使用的“骚操作”,有兴趣入群的同学,可以长扫描区域二维码,一定要注意事项:城市+昵称+技术方向,根据格式备注,可快速通过。▲长按扫描
                      文章源自JAVA秀-https://www.javaxiu.com/42858.html

                      文章源自JAVA秀-https://www.javaxiu.com/42858.html

                      真实案例:Feign切换client到okhttp无法生效,被老大骂的有点慌!热门推荐:文章源自JAVA秀-https://www.javaxiu.com/42858.html

                      真实案例:Feign切换client到okhttp无法生效,被老大骂的有点慌!文章源自JAVA秀-https://www.javaxiu.com/42858.html

                      真实案例:Feign切换client到okhttp无法生效,被老大骂的有点慌!真实案例:Feign切换client到okhttp无法生效,被老大骂的有点慌!文章源自JAVA秀-https://www.javaxiu.com/42858.html

                      文章源自JAVA秀-https://www.javaxiu.com/42858.html
                      继续阅读
                      速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html
                      weinxin
                      资源分享QQ群
                      本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
                      沙海
                      匿名

                      发表评论

                      匿名网友 填写信息

                      :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

                      确定