zoukankan      html  css  js  c++  java
  • springboot搭建http2服务器和h2c服务器 h2 的http/https 请求服务器

    HTTP2.0特性
    通俗易懂篇:https://www.cnblogs.com/yingsmirk/p/5248506.html
    深入了解篇:https://www.jianshu.com/p/67c541a421f9
    HTTP/2连接是建立在TCP连接之上的应用层协议,客户端是TCP连接的发起者。

    HTTP/2使用和HTTP/1.1一样的 URI schemes:"http" 和 "https",并且还是共享同样的默认端口:http的80,https的443。这意味着,对于"http" 和 "https"确定其是否支持HTTP/2协议的方式是不同的。

    在官方文档中,为HTTP/2协议定义了两个版本:h2 和 h2c:

    h2版本的协议是建立在TLS层之上的HTTP/2协议,这个标志被用在TLS应用层协议协商(TLS-ALPN)域和任何其它的TLS之上的HTTP/2协议。
    h2c版本是建立在明文的TCP之上的HTTP/2协议,这个标志被用在HTTP/1.1的升级协议头域和其它任何直接在TCP层之上的HTTP/2协议。
    搭建带有证书的h服务端:https://
    要使用HTTP/2需要注意以下几点

    1.虽然HTTP/2没有明确要求必须使用TLS,但当前几乎所有浏览器均只支持 HTTP/2 Over TLS。所以在使用之前我们需要先制作一张证书。

    2.如果您的项目中用的是tomcat或jetty,它们并不能直接支持HTTP/2,但是undertow可以。具体可以参考Spring Boot的文档:https://docs.spring.io/spring-boot/docs/2.0.5.RELEASE/reference/htmlsingle/#howto-configure-http2

    3.我们制作的证书是不被浏览器认可的,所以会有安全提示,不能用于生产环境。

    在本文的例子中使用的是undertow。

    1.制作证书:

    使用JDK自带的keytool,证书类型为:PKCS12

    打开cmd 输入下面的命令:

    keytool -genkey -alias undertow -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -dname "CN=localhost, OU=localhost, O=localhost, L=hangzhou, ST=zhejiang, C=CN"

    输入密钥库口令:

    再次输入新口令:

    执行时会要求输入证书口令,这里输入的是123456。执行完命令后会在执行的文件夹生成一个keystore.p12的文件。

    keytool

    -genkey

    -alias undertow (别名)

    -storetype PKCS12 (证书类型)

    -keyalg RSA (算法)

    -keysize 2048 (秘钥长度)

    -keystore keystore.p12 (指定生成证书的位置和证书名称)

    -dname "

    CN=localhost,(姓名姓氏)

     OU=localhost,(组织单位)

     O=localhost,(组织名称)

     L=hangzhou,(所在城市或者区域名称)

     ST=zhejiang,(所在的省/市/自治区名称)

     C=CN"(该单位的双字母国家/地区代码)

    keytool的详细用法:

    https://docs.oracle.com/javase/8/docs/technotes/tools/windows/keytool.html

    常见的证书格式及其说明参考:

    http://www.cnblogs.com/xq1314/archive/2017/12/05/7987216.html

    配置Web容器
    spring boot默认使用的是tomcat,我们需要先将tomcat移除,然后换成undertow。

    在搭建好的springboot项目中引入  注意springboot在2.0版本才开始支持http2,springboot2.0 支持的jdk最低版本为java8

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-web</artifactId>

        <exclusions>

            <exclusion>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-starter-tomcat</artifactId>

            </exclusion>

        </exclusions>

    </dependency>

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-undertow</artifactId>

    </dependency>

    如果不移除tomcat依赖会一直以Tomcat作为容器启动。

    然后将刚才生成的keystore.p12拷贝到src/main/resources下。

    然后在application.properties中配置服务器信息。

    #端口号
    server.port=8443
    #ip地址
    server.address=0.0.0.0

    #启用HTTP响应压缩
    server.compression.enabled=true
    # 启用http2
    server.http2.enabled=true
    # 启用ssl
    server.ssl.enabled=true
    #证书位置
    server.ssl.key-store=classpath:keystore.p12
    # 证书密码
    server.ssl.key-store-password=123456
    # 证书类型
    server.ssl.key-store-type= PKCS12
    # 协议类型
    server.ssl.protocol=TLSv1.2
    server.ssl.key-alias=undertow
    这时如果启动服务器,是只支持https的。


    @SpringBootApplication
    public class DemoApplication implements WebServerFactoryCustomizer<UndertowServletWebServerFactory>{

       public static void main(String[] args) {
          SpringApplication.run(DemoApplication.class, args);
       }

       @Override
       public void customize(UndertowServletWebServerFactory undertowServletWebServerFactory) {
          undertowServletWebServerFactory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
             @Override
             public void customize(Undertow.Builder builder) {
                builder.addHttpListener(8080, "0.0.0.0");
             }

          });
       }
    }
    这里增加8080端口的监听,配置参考:

    https://docs.spring.io/spring-boot/docs/2.0.5.RELEASE/reference/htmlsingle/#howto-configure-webserver

    https://docs.spring.io/spring-boot/docs/2.0.5.RELEASE/reference/htmlsingle/#howto-enable-multiple-listeners-in-undertow

    启动后可以看到控制台打印出如下信息:

    测试
    增加一个测试控制器

    浏览器访问:https://192.168.110.117:8443/someData

    观察两次请求的size,一次是92一次是70,这是因为HTTP/2的头部压缩技术。

    浏览器访问:http://localhost:8080/someData   HTTP/1.1协议 而且数据包要比HTTP/2的数据包大,并且无论刷新多少次,大小是不变的。

    搭建h2c服务端:http://


     

    从Spring boot 2.0的官方文档上看,明确写明了“Spring boot 不支持h2c —— HTTP/2协议的明文版本”,于是就想其它办法来支持h2c。

    首先,想的是通过外置的tomcat配置来支持h2c,因为tomcat8.5中的server.xml配置中,有HTTP/2协议相关的配置:

    这里显示要添加证书,明显支持的是基于TLS层之上的h2版本的HTTP/2协议,但是从配置上可以禁用SSL,于是就尝试了一下,果然成功了。配置成如下示例,就支持h2c了:

    <Connector port="5080" protocol="HTTP/1.1" connectionTimeout="20000">

        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" /></Connector>

    tomcat容器自身是支持多个connector的配置的,查看springboot2.0是否支持同时配置多个Connector

    文档中示例是通过 java configure 的方式配置一个https的connector,在application.properties中不支持配置多个connector。

    因此模仿这外置tomcat配置h2c的方式,在Spring boot 2.0 的内置tomcat中通过java configure的方式配置h2c协议,具体代码如下:

    新建一个springboot项目,加入以下配置即可

    /

    **
     * h2c协议
     * @return
     */
    @Bean
    public ServletWebServerFactory servletContainer() {
       TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
       tomcat.addAdditionalTomcatConnectors(createH2cConnector());
       return tomcat;
    }

    private Connector createH2cConnector() {
       Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
       Http2Protocol upgradeProtocol = new Http2Protocol();
       connector.addUpgradeProtocol(upgradeProtocol);
       //connector.setScheme("http");
       connector.setPort(5080);

       return connector;
    }
    这时启动我们的Spring boot应用,会发现最后的启动日志有两个端口

    因为浏览器只支持h2 所以使用curl 验证h2c的服务端 或者用wireshark抓包查看

    检查你的curl是否支持http2

    从上面的 Features 信息发现,我的curl工具是支持HTTP/2协议的。

    下面开始验证我Spring boot 的服务在5080端口是否是h2c,具体如下:

    输入curl -v  --http2 "http://192.168.110.117:5080/someData"

    从结果看 已经验证通过。

  • 相关阅读:
    Jdbc增删改查的相关操作(Oracle 数据库环境)
    java
    今日随笔
    爬虫之链家网
    爬虫之搜狗
    【题解】「UVA1149」装箱 Bin Packing
    【题解】「SP34013」SEUG
    【题解】「SP867」 CUBES
    【题解】NOI 系列题解总集
    APIO2019简要题解
  • 原文地址:https://www.cnblogs.com/exmyth/p/14824244.html
Copyright © 2011-2022 走看看