• OpenFeign中使用明文http2


    OpenFeign中使用明文http2

    如果想使用openfeign支持http2,只需其底层的client支持即可。

    目前openfeign支持的client有:

    • URLConnection: java9之前不支持http2
    • Apache HttpClient: 据说5.0开始支持,目前4.X不支持
    • OKHttp: 支持, h2或者H2_PRIOR_KNOWLEDGE(明文http2)都支持,目前找到最好用的。

    由于服务内网,在此没有走TLS, 因此只能选用OKHttp。

     步骤:

    • 服务端启用Http2
    • 客户端更改feign底层client

    1、服务端

    正常springcloud项目

    在此直接使用undertow来启用http2:

    pom依赖, 为了使用undertow:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <groupId>org.springframework.boot</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- 使用undertow代替tomcat -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-undertow</artifactId>
    </dependency>

     由于undertow直接在配置server.http2.enabled=true不起作用,需要以下配置:

    import io.undertow.UndertowOptions;
    import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class WebConfig {
        @Bean
        public UndertowServletWebServerFactory embeddedServletContainerFactory() {
            UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
            factory.addBuilderCustomizers(builder -> builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true));
            return factory;
        }
    }

    2、客户端

    1、引入openfeign及okhttp:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-okhttp</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp</artifactId>
        <version>4.1.0</version>
    </dependency>

    2、application.yml中配置以下内容,用于启用okhttp

    feign:
      okhttp:
        enabled: true

    3、为了使用明文http2,需要手动指定其协议,配置如下:

    @Bean
    public okhttp3.OkHttpClient okHttpClient(){
        List<Protocol> protocols = new ArrayList<>();
        protocols.add(Protocol.H2_PRIOR_KNOWLEDGE);
        OkHttpClient.Builder builder = new okhttp3.OkHttpClient.Builder()
                .readTimeout(60, TimeUnit.SECONDS)
                .connectTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(120, TimeUnit.SECONDS)
                .connectionPool(new ConnectionPool());
        // 添加拦截器用于打印响应时所使用的协议
        builder.addInterceptor(new ResponseInterceptor());
        builder.protocols(protocols);
        return builder.build();
    }

    拦截器为了打印响应的协议,或者直接通过debug模式查看也可:

    import okhttp3.Interceptor;
    import okhttp3.Request;
    import okhttp3.Response;
    import org.jetbrains.annotations.NotNull;
    
    import java.io.IOException;
    
    public class ResponseInterceptor implements Interceptor {
        @NotNull
        @Override
        public Response intercept(@NotNull Chain chain) throws IOException {
            Request request = chain.request();
            try {
                Response response = chain.proceed(request);
                System.out.println(response.protocol());
                return response;
            } catch (Exception e) {
                e.printStackTrace();
                throw e;
            }
        }
    }

    feign接口定义如下:

    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    
    import java.util.Map;
    
    @FeignClient("demo3-service")
    public interface Demo3Service {
    
        @GetMapping("/v1/demo3/demo")
        Map<String, String> demo();
    }

    4、通过代码调用,其打印结果为:h2_prior_knowledge

    @Autowired
    private Demo3Service demo3Service;
    
    @GetMapping("/demo3")
    public Map<String, String> demo3() throws Exception {
        return demo3Service.demo();
    }
  • 相关阅读:
    仿360拖拽
    js 鼠标拖拽元素移动
    js 随机生成颜色
    vue多视图
    vue 全局组件的注册
    一键分享到QQ空间、QQ好友、新浪微博、微信代码
    vuex如何管理需要即时更新的全局变量
    js检测是哪个浏览器
    for in,Object.keys()与for of的用法与区别
    js三元运算符
  • 原文地址:https://www.cnblogs.com/lizm166/p/16820799.html
Copyright © 2020-2023  润新知