Tomcat架构解析之HTTP/2.0

一、前言

    自8.5版本开始,Tomcat增加了对HTTP/2.0的支持。在这篇博客中,我们将简单介绍HTTP/2.0的发展、基本知识以及其配置使用方式。

二、基础知识

    谈到HTTP/2.0,就不得不先说一下SPDY协议。SPDY是Google考法的用于传输Web内容的开发网络协议,可以说是HTTP/2.0的母体。SPDY通过巧妙地控制HTTp通信,以达到降低Web页面加载延迟和提高Web安全的目标。SPDY通过压缩、多路复用】优先级来实现降低延迟,但是这有赖于网络和Web应用部署条件组合。

    SPDY的设计目标是降低Web页面加载时间。通过优先级和多路复用,SPDY使得只需要建立一个TCP链接即可传送网页内容以及图片等资源。SPDY中广泛应用了TLS加密,传输内容也均以GZIP或者DEFLATE歌手压缩(与HTTP不同,HTTP的头部并不会被压缩)。另外,除了像HTTP网页服务器被动等待浏览器发起请求外,SPDY网页服务器还可以主动向浏览器推送内容。

    SPDY并不是用于取代HTTP协议的,他修改了HTTP请求和响应在网络上的传输方式。这意味着只需要增加一个SPDY传输层,现有所有服务端应用均不需要做任何的修改。SPDY是HTTP和HTTPS协议的有效通道。当通过SPDY发送时,HTTP请求会被处理、标记简化和压缩。例如,每一个SPDY端点会持续跟踪在之前请求中已经发送的HTTP报文头部,从而避免重复发送还未改变的头部,未发送的报文数据部分将在压缩后发送。

    考虑到SPDY已经获得的实现者的支持以及与HTTP/1.1相比获得的性能提升mHTTPbis工作小组最终决定采用SPDY/2作为HTTP/2的基础,而且SPDY/4已经与HTTP/2草稿非常接近。

    Tomcat在8.0的最初几个版本中,增加了对SPDY/2协议的支持,以用于实验目的。随着在8.5版本中对HTTP/2.0的支持,SPDY/2的相关功能已经移除。

    虽然HTTP/2.0托体育SPDY/2,但是仍有育SPDY不同之处,主要有一下两点:

  • HTTP/2.0支持明文传输,二SPDY强制使用HTTPS。
  • HTTP/2.0消息头的压缩算法采用HPACK,而SPDY采用DELEFT。

    与HTTP/1.1相比,HTTP/2.0在传输方面进行了如下重要改进:

  • 采用二进制格式传输数据而非HTTP/1.1的文本格式。
  • 基于帧和流的多路复用,真正实现了基于一个链接的多请求并发处理。
  • 支持服务器推送。

    在HTTP/2.0中,一个基本的协议单元是帧。帧在HTTP/2.0中的概念可以理解为数据包之于TCP的概念。按照用途不同,分为不同类型 帧,如HEADERS和DATA帧用于HTTP的请求和响应,而如SETTINGS、WINDOW_UPDATE、PUSH_PROMISE等则用于支持HTTP/2.0的特性。

    一个Frame由9个字节长头以及变长的Payload组成,具体格式如下图所示:
在这里插入图片描述

  • Length:24位,表示Frame Payload部分的长度。

  • Type:8位,表示Frame的类型。帧类型决定了帧的格式和语义。

  • Flags:8位,每一位是一个布尔标记,用于特定的帧类型。对于每个类型的帧,这些标记都被赋予了特殊的语义。例如发送最后一个DATA类型的Frame时,就会将Flags最后一位设置为1,表示END_STREAM。说明当前Frame是流的最后一个数据包。

  • R:1位预留为,未明确定义语义。

  • Steam Identifier:Frame所属流的标识。标识0作为预留值用于链接初始化,而非某个Frame。

  • Frame Payload:Frame的有效荷载,每种类型的帧的Payload格式的语义均不相同。不论是HTTP Header还是Body,在HTTP/2.0中,都会被存储到Frame Payload中,组成Frame进行发送。他们通过Frame Header中的Type进行区分,如下图所示:
    在这里插入图片描述
           Stream(流)是客户端与服务器之间通过HTTP/2.0链接交换的独立的、双向的帧序列,我们可以将流视为一个完整的处理过程(请求/响应)。流的概念的提出是为了实现HTTP请求的多路复用,他具有如下特征:

  • 一个HTTP/2.0链接可以并发的打开多个流,并可以从多个流的任意端点交换帧。

  • 流可以创建并且被客户端/服务器单边或共享使用。

  • 流可以被任意端点关闭。

  • 同一个流中的帧按照顺序发送,接收者按照接收顺序进行处理。

  • 流通过一个整数唯一标识,由初始化流的端点分配。

  • 流是相互独立的,因此一个流的阻塞或者停止的请求/响应并不会影响其他流的处理。

    可以通过如下图示意流通过HTTP/2.0链接的传输的过程。
在这里插入图片描述
    流将一次请求过程拆分为有序的更细粒度的帧,便拥有自己的生命周期和状态转换,我们每发送或者接收帧都会导致流状态的变化,从而可以确保流按照既定的规则和顺序接收帧。流的生命周期如下图所示:
在这里插入图片描述
    采用流进行多路复用会导致TCP资源竞争,HTTP/2.0通过流控制确保流之间不会严重影响彼此。除此之外,通过引入优先级机制,可以使端点告知对端他希望对端在管理并发流时如何分配资源,以便给予指定流更多的资源支持。不仅如此,通过指定流之间的依赖关系,也可以影响资源的分配。

三、配置方式

    由前面的讲解可知,在Tomcat中,通过UpgradeProtocol接口提供HTTP/2.0升级支持。因此,若要为HTTP链接器开启HTTP/2.0支持,只需要添加如下配置即可:
在这里插入图片描述
    HTTP/2.0同时支持TLS(h2)和非TLS(h2c)。如果希望使用TLS,那么需要为链接器添加证书信息。由于JDK8的TLS实现不支持ALPAN,因此我们需要采用基于OpenSSL的TLS实现,同时指定链接器的sslImplementationName属性,如下所示:
在这里插入图片描述
    当然,如果使用的是Http11Aprprotocol,则不需要指定sslImplementationName,因为Http11AprProtocol默认采用的便是OpenSSL。

发布了185 篇原创文章 · 获赞 457 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/weixin_42146366/article/details/98075232