HTTP2.0学习 与 Nginx和Tomcat配置HTTP2.0
一、HTTP2.0
1.1 简介
HTTP/2(超文本传输协议第2版,最初命名为HTTP 2.0),简称为h2(基于TLS/1.2或以上版本的加密连接)或 h2c(非加密连接),是HTTP协议的的第二个主要版本。
1.2 新的特性
具体可以看这篇文章: https://segmentfault.com/a/1190000013420784
头数据压缩 Data compression of HTTP headers
服务器推送 HTTP/2 Server Push
管线化请求 Pipelining of requests.
对数据传输采用多路复用,让多个请求合并在同一 TCP 连接内 Multiplexing multiple requests over a single TCP connection, 因为每一个tcp 连接在创建的时候都需要耗费资源,而且在创建初期,传输也是比较慢的。
采用了二进制而非明文来打包、传输 客户端<——>服务器 间的数据。
1.3 h2c 的支持度
HTTP/2 的设计本身允许非加密的 HTTP 协议,也允许使用 TLS 1.2 或更新版本协议进行加密。协议本身未要求必须使用加密,惟多数客户端 (例如 Firefox, Chrome, Safari, Opera, IE, Edge) 的开发者声明,他们只会实现通过TLS加密的HTTP/2协议,这使得经 TLS加密的HTTP/2(即h2)成为了事实上的强制标准,而 h2c事实上被主流浏览器废弃。
二、Nginx 对 http2.0 的支持
2.1 Nginx 作为服务端使用http2.0
使用 http2.0 的条件
- Nginx 版本大于或等于 1.9.5 。
 - openssl 版本 等于或者大于OpenSSL 1.0.2
 - 编译的时候开启
 --with-http_v2_module我们这里配置的 h2 ,因为 浏览器对 h2c 基本不支持。
Nginx 在 1.9.5 才开始引入 http2.0 ,官方日志。
编译的时候加入 --with-http_v2_module,然后在 Nginx 配置中加上 http2
示例
listen 443 ssl http2 default_server;
2.2 Nginx 作为客户端使用 http2.0
Nginx 作为服务端是可以进行配置 http2.0 的, 但是 Nginx 如果作为客户端的话。Nginx 官方说的是不支持
Q: Will you support HTTP/2 on the upstream side as well, or only support HTTP/2 on the client side?
A: At the moment, we only support HTTP/2 on the client side. You can’t configure HTTP/2 with proxy_pass. [Editor – In the original version of this post, this sentence was incorrectly transcribed as “You can configure HTTP/2 with proxy_pass.” We apologize for any confusion this may have caused.]
But what is the point of HTTP/2 on the backend side? Because as you can see from the benchmarks, there’s not much benefit in HTTP/2 for low‑latency networks such as upstream connections.
Also, in NGINX you have the keepalive module, and you can configure a keepalive cache. The main performance benefit of HTTP/2 is to eliminate additional handshakes, but if you do that already with a keepalive cache, you don’t need HTTP/2 on the upstream side.
不能使用 proxy_pass配置 http2.0,  http2.0性能的主要优势是减少多次tcp连接,我们通过配置keepalive  也可以做到这点。  (Google翻译总结)
后续可以了解下  grpc  .
grpc_pass grpc://localhost:50051
三、Tomcat 对 HTTP2.0 的支持
看了下 8.0 版本, 是不支持 HTTP2.0 。
看了下 8.5版本, 是支持 HTTP2.0。
3.1 、Tomcat 8.5
怕上面文档没有看清,下面文中的 h2 指的是(基于TLS/1.2或以上版本的加密连接),h2c 是非加密的
非加密的,用浏览器是访问不了的(因为现在浏览器现在不支持),只支持 h2 。
官方文档写到
Tomcat 是支持 h2    和 h2c 的。 (你服务端支持没有用啊,客户端不支持,这不就gg了)
HTTP/2 is support is provided for TLS (h2), non-TLS via HTTP upgrade (h2c) and direct HTTP/2 (h2c) connections. To enable HTTP/2 support for an HTTP connector the following UpgradeProtocol element must be nested within the Connector with a className attribute of org.apache.coyote.http2.Http2Protocol.
<Connector ... >
  <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
</Connector>
Because Java 8's TLS implementation does not support ALPN (which is required for HTTP/2 over TLS), you must be using an OpenSSL based TLS implementation to enable HTTP/2 support. See the sslImplementationName attribute of the Connector.
Additional configuration attributes are available. See the HTTP/2 Upgrade Protocol documentation for details.
3.1.1、依赖环境
需要安装 openssl   版本大于或者等于1.0.2 。
yum install  openssl
3.1.2、h2c 配置(非加密)
也就加 <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
示例配置
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150">
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
</Connector>
日志中可以看到
The ["http-nio-8080"] connector has been configured to support HTTP upgrade to [h2c]
也就意味着 h2c 配置好了。
我们进行测试,使用的是curl, 但是这个 需要最新的版本,具体可以看扩展内容。
# curl --http2  http://192.168.174.128:8080
# tomcat 日志
192.168.174.128 - - [26/Mar/2020:09:54:28 +0800] "GET / HTTP/1.1" 101 -
192.168.174.128 - - [26/Mar/2020:09:54:28 +0800] "GET / HTTP/2.0" 200 11195
# 101 是转换协议,也就是 转为协议为 http2.0 . 第二条日志也就证实了。
3.1.3、h2 配置(加密)
也就意味着要进行配置证书了,
这个是8.5.53 版本的默认配置
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
         This connector uses the APR/native implementation which always uses
         OpenSSL for TLS.
         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
         configuration is used below.
    -->
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         certificateChainFile="conf/localhost-rsa-chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
示例配置
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
       <SSLHostConfig>
            <Certificate certificateKeyFile="conf/server.key"
                         certificateFile="conf/ca.crt"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
配置成功日志
The ["https-openssl-nio-8443"] connector has been configured to support negotiation to [h2] via ALPN
访问
 curl  --http2 -k   https://192.168.174.128:8443
 # 查看 tomcat 的 localhost_access_log 日志
 192.168.174.128 - - [26/Mar/2020:10:36:03 +0800] "GET / HTTP/2.0" 200 11195
发现 OK。
浏览器进行访问,也是ok。

四、扩展
4.1、测试 h2c
需要安装 curl ,curl 新版本的才支持,老版本不支持 http2.0.
rpm -ivh http://mirror.city-fan.org/ftp/contrib/yum-repo/city-fan.org-release-2-1.rhel7.noarch.rpm
yum clean all
yum makecache
yum update curl   --enablerepo=city-fan.org
# 可以看到 http2.0 就意味着支持了。
curl  -V
curl 7.69.1 (x86_64-redhat-linux-gnu) libcurl/7.69.1 NSS/3.44 zlib/1.2.7 libpsl/0.7.0 (+libicu/50.1.2) libssh2/1.9.0 nghttp2/1.31.1
Release-Date: 2020-03-11
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS GSS-API HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz Metalink NTLM NTLM_WB PSL SPNEGO SSL UnixSockets
参考文章: https://www.cnblogs.com/brookin/p/10713166.html
4.2、查看浏览器是否支持 http2.0
查看我们的浏览器是否支持 http2.0, 打开网址进行测试。
4.3、查看网站是否支持 http2.0
网址, 需要越墙。
4.4、JAVA8 如何支持 HTTP2.0 TLS
问题
java8 的 TLS 不支持 ALPN(http2.0 TLS 需要ALPN)
# http://tomcat.apache.org/tomcat-8.5-doc/config/http.html#HTTP/2_Support
Because Java 8's TLS implementation does not support ALPN (which is required for HTTP/2 over TLS), you must be using an OpenSSL based TLS implementation to enable HTTP/2 support. See the sslImplementationName attribute of the Connector. java8 的 TLS 不支持 ALPN(http2.0 TLS 需要ALPN),我们必须基于 OpenSSL的TLS实现来启用HTTP/2支持。
默认使用 org.apache.tomcat.util.net.jsse.JSSEImplementation,但在 Java8 情况下不支持 ALPN。
# http://tomcat.apache.org/tomcat-8.5-doc/config/http.html#HTTP/2_Support
When APR/native is enabled, the connectors will default to using OpenSSL through JSSE, which may be more optimized than the JSSE Java implementation depending on the processor being used, and can be complemented with many commercial accelerator components. The following NIO and NIO2 SSL configuration attributes are not specific to a virtual host and, therefore, must be configured on the connector.
也就是说当 APR/native 开启了, 连接器会默认使用 OpenSSL
解决
方法一(没行通)
我们需要关注这个参数:sslImplementationName
sslImplementationName
The class name of the SSL implementation to use. If not specified and the tomcat-native library is not installed, the default of org.apache.tomcat.util.net.jsse.JSSEImplementation will be used which wraps JVM's default JSSE provider. Note that the JVM can be configured to use a different JSSE provider as the default. Tomcat also bundles a special SSL implementation for JSSE that is backed by OpenSSL. To enable it, the native library should be enabled as if intending to use the APR connector, and Tomcat will automatically enable it and the default value of this attribute becomes org.apache.tomcat.util.net.openssl.OpenSSLImplementation. In that case, the attributes from either JSSE and OpenSSL configuration styles can be used, as long as the two types are not mixed (for example, it is not allowed to define use of a Java keystore and specify a separate pem private key using the OpenSSL attribute).
当我们没有安装 tomcat-native ,将默认使用 org.apache.tomcat.util.net.jsse.JSSEImplementation,但是这个是不支持 ALPN,也就不支持 http2.0了。
看官方说到我可以配置   sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation" ,但是我进行配置这个启动就失败了
	org.apache.catalina.LifecycleException: 初始化组件[Connector[HTTP/1.1-8443]]失败。
		at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:440)
		at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:139)
		at org.apache.catalina.core.StandardService.initInternal(StandardService.java:552)
		at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
		at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:848)
		at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
		at org.apache.catalina.startup.Catalina.load(Catalina.java:639)
		at org.apache.catalina.startup.Catalina.load(Catalina.java:662)
		at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
		at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
		at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.lang.reflect.Method.invoke(Method.java:498)
		at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:303)
		at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473)
	Caused by: java.lang.UnsatisfiedLinkError: org.apache.tomcat.jni.Pool.create(J)J
		at org.apache.tomcat.jni.Pool.create(Native Method)
方法二(可行)
安装  tomcat-native,只要本地安装了 tomcat-native ,就会默认使用 openssl.  虽然我们没有开启 ARP
yum install   openssl   tomcat-native  -y
Tomcat 开启ARP 文章
因此我们建议,你在 java 8的 环境下需要使用 h2 的话,需要做到以下几点
- 安装 openssl 大于等于 1.0.2。
 - 使用 Tomcat 8.5
 - 安装 tomcat-native。
 
HTTP2.0学习 与 Nginx和Tomcat配置HTTP2.0的更多相关文章
- Nginx、Tomcat配置https
		
一.Nginx.Tomcat配置https 前提就是已经得到了CA机构颁发的证书 一.合并证书 1.假设证书文件如下 秘钥文件server.key,证书CACertificate-INTERMEDIA ...
 - nginx和tomcat配置负载均衡和session同步
		
一.背景 因业务需求,现需配置多台服务器,实现负载均衡. 二.解决方案 使用 nginx + tomcat,在这一台应用服务器部署一个nginx和两个tomcat.通过nginx修改配置后reload ...
 - Nginx和Tomcat配置SSL实现https访问
		
环境:CentOS 7 Nginx版本: nginx/1.18.0 1. 安装nginx 详细步骤可以参考如下官网:http://nginx.org/en/linux_packages.html#RH ...
 - nginx,apache,tomcat配置https的阿里提供的文档
		
安装证书 ( 1 ) 打开 Nginx 安装目录下 conf 目录中的 nginx.conf 文件,找到 # HTTPS server # #server { # listen 443; # serv ...
 - OAuth2.0学习(2-1)Spring Security OAuth2.0 开发指南
		
开发指南:http://www.cnblogs.com/xingxueliao/p/5911292.html Spring OAuth2.0 提供者实现原理: Spring OAuth2.0提供者实际 ...
 - OAuth2.0学习(1-12)开源的OAuth2.0项目和比较
		
OAuth2.0学习(2-1)OAuth的开源项目 1.开源项目列表 http://www.oschina.net/project/tag/307/oauth?lang=19&sort=t ...
 - 使用nginx和tomcat配置反向代理和动静分离
		
背景 本人主修的编程语言是Java语言,因此最开始接触的Web开发也是JSP技术.使用Java开发的Web应用需要部署在专门的服务器程序上运行,比如Tomcat.但是一般很少会有人将Tomcat作为用 ...
 - Spring4.0学习笔记(7) —— 通过FactoryBean配置Bean
		
1.实现Spring 提供的FactoryBean接口 package com.spring.facoryBean; import org.springframework.beans.factory. ...
 - apache、nginx、tomcat配置方法
		
https://www.cnblogs.com/chenmh/p/5121830.html
 
随机推荐
- Memcached笔记——(三)Memcached使用总结
			
为了将N个前端数据同步,通过Memcached完成数据打通,但带来了一些新问题: 使用iBatis整合了Memcached,iBatis针对每台server生成了唯一标识,导致同一份数据sql会产生不 ...
 - BufferedReader中文乱码解决
			
做一个从windows cmd截获命令返回值的java程序,结果截回来的文字中所有的中文都是乱码 Microsoft Windows [�汾 6.1.7260] ��Ȩ���� (c) 2009 Mi ...
 - FBI今年最重要的任务:招募黑客
			
 当FBI(联邦调查局)一次又一次被爆出丑闻的时候,面临着一个又一个的尴尬局面.在这样的情况下,FBI发现了自己的一个巨大问题,那就是以前都依靠隐秘行动和人员的保密性来保证国家的安全,现在必须依靠更 ...
 - 10分钟进阶SpringBoot - 05. 数据访问之JDBC(附加源码分析+代码下载)
			
10分钟进阶SpringBoot - 05. 数据访问之JDBC 代码下载:https://github.com/Jackson0714/study-spring-boot.git 一.JDBC是什么 ...
 - http协议入门---转载
			
http协议入门 ##(一). HTTP/0.9 HTTP 是基于 TCP/IP 协议的应用层协议.它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口. 最早 ...
 - 7-44 jmu-python-区间数之和 (10 分)
			
输入一个区间,计算里面能被3整除或被5整除的数和. 输入格式: 每行输入一个数据,代表区间左界和右界.区间包含左界和右界.数据必须是整数. 输出格式: 满足条件数和. 输入样例: 2 10 输出样例: ...
 - 7-42 jmu-python-找字符 (15 分)
			
输入一个字符串及字符,输出第一次出现该字符的位置. 输入格式: 行1:输入字符串 行2:输入一个字符 输出格式: 找到,输出对应位置,格式index=X的, X表示查找到位置 找不到,输出can't ...
 - git工作中常用操作总结
			
这篇文章主要记录下工作中常用的git操作.主要是对之前文章记录的问题做个总结,这个其实在idea中操作更加简单 别名配置 在敲git 命令时,其实可以使用别名,比如 commit可以配置为ci 下面是 ...
 - tomcat启动出现问题,有待解决
			
三月 15, 2017 2:23:41 下午 org.apache.tomcat.util.digester.SetPropertiesRule begin警告: [SetPropertiesRule ...
 - All In One
			
set1 https://github.com/tianhang-f... set2 https://github.com/tianhang/F... set3https://github.com/t ...