美文网首页
Spring Cloud全解析:服务调用之OpenFeign集成

Spring Cloud全解析:服务调用之OpenFeign集成

作者: 墨线宝 | 来源:发表于2024-09-29 10:36 被阅读0次

    OpenFeign集成OkHttp

    OpenFeign本质是HTTP来进行服务调用的,也就是需要集成一个Http客户端。

    使用的是Client接口来进行请求的

    public interface Client {
    
     // request是封装的请求方式、参数、返回值类型
      // options 是连接超时、读取超时等的配置项
      Response execute(Request request, Options options) throws IOException;
    }
    

    默认是HttpURLConnection方式,也就是jdk中提供的最原始的那个

    public static class Default implements Client {
    
      @Override
      public Response execute(Request request, Options options) throws IOException {
        HttpURLConnection connection = convertAndSend(request, options);
        return convertResponse(connection).toBuilder().request(request).build();
      }
    }
    

    HTTP连接需要进行TCP三次握手,是一个比较耗时的操作,一般我们不直接使用HttpURLConnection,而是使用HttpClient/okHttp等支持连接池的客户端工具,以Feign集成OkHttp为例

    添加依赖

            <dependency>
                <groupId>io.github.openfeign</groupId>
                <artifactId>feign-okhttp</artifactId>
            </dependency>
    

    其包内有一个Client的实现类OkHttpClient,

    public final class OkHttpClient implements Client {
    
      @Override
      public feign.Response execute(feign.Request input, feign.Request.Options options)
          throws IOException {
        okhttp3.OkHttpClient requestScoped;
        if (delegate.connectTimeoutMillis() != options.connectTimeoutMillis()
            || delegate.readTimeoutMillis() != options.readTimeoutMillis()) {
          requestScoped = delegate.newBuilder()
              .connectTimeout(options.connectTimeoutMillis(), TimeUnit.MILLISECONDS)
              .readTimeout(options.readTimeoutMillis(), TimeUnit.MILLISECONDS)
              .followRedirects(options.isFollowRedirects())
              .build();
        } else {
          requestScoped = delegate;
        }
        Request request = toOkHttpRequest(input);
        Response response = requestScoped.newCall(request).execute();
        return toFeignResponse(response, input).toBuilder().request(input).build();
      }
    }
    

    配置连接池

    import okhttp3.ConnectionPool;
    import okhttp3.OkHttpClient;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.net.ssl.*;
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.security.cert.X509Certificate;
    import java.util.concurrent.TimeUnit;
    
    @Configuration
    public class OkHttpConfig {
        /**
         * OkHttp 客户端配置
         *
         * @return OkHttp 客户端配
         */
        @Bean
        public OkHttpClient okHttpClient() {
            return new OkHttpClient.Builder()
                    .sslSocketFactory(sslSocketFactory(), x509TrustManager())
                    .hostnameVerifier(hostnameVerifier())
                    .retryOnConnectionFailure(false)    //是否开启缓存
                    .connectionPool(pool())             //连接池
                    .connectTimeout(15L, TimeUnit.SECONDS) // 连接超时时间
                    .readTimeout(15L, TimeUnit.SECONDS) // 读取超时时间
                    .followRedirects(true) // 是否允许重定向
                    .build();
        }
    
        /**
         * 忽略证书校验
         *
         * @return 证书信任管理器
         */
        @Bean
        public X509TrustManager x509TrustManager() {
            return new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
                }
    
                @Override
                public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
                }
    
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            };
        }
    
        /**
         * 信任所有 SSL 证书
         *
         * @return
         */
        @Bean
        public SSLSocketFactory sslSocketFactory() {
            try {
                TrustManager[] trustManagers = new TrustManager[]{x509TrustManager()};
                SSLContext sslContext = SSLContext.getInstance("SSL");
                sslContext.init(null, trustManagers, new SecureRandom());
                return sslContext.getSocketFactory();
            } catch (NoSuchAlgorithmException | KeyManagementException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 连接池配置
         *
         * @return 连接池
         */
        @Bean
        public ConnectionPool pool() {
            // 最大连接数、连接存活时间、存活时间单位(分钟)
            return new ConnectionPool(200, 5, TimeUnit.MINUTES);
        }
    
        /**
         * 信任所有主机名
         *
         * @return 主机名校验
         */
        @Bean
        public HostnameVerifier hostnameVerifier() {
            return (s, sslSession) -> true;
        }
    }
    

    yml配置

    要开启OkHttp ,还需要在YML 中添加开启配置项,默认是关闭的

    feign:
      okhttp:
        enabled: true
    

    至于为什么需要配这个,看一下FeignAutoConfiguration中装配OkHttp的条件

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnClass(OkHttpClient.class)
    @ConditionalOnMissingClass("com.netflix.loadbalancer.ILoadBalancer")
    @ConditionalOnMissingBean(okhttp3.OkHttpClient.class)
    @ConditionalOnProperty("feign.okhttp.enabled")
    protected static class OkHttpFeignConfiguration
    

    参考文献

    相关文章

      网友评论

          本文标题:Spring Cloud全解析:服务调用之OpenFeign集成

          本文链接:https://www.haomeiwen.com/subject/okzrrjtx.html