HTTP/2深入学习

目录

一、HTTP/2背景

     HTTP/2即超文本传输协议,是下一代HTTP协议。是由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis (httpbis)工作小组进行开发。是自1999年http1.1发布后的首个更新。HTTP 2.0在2013年8月进行首次合作共事性测试。在开放互联网上HTTP/2将只用于https://网址,而 http://网址将继续使用HTTP/1,目的是在开放互联网上增加使用加密技术,以提供强有力的保护去遏制主动攻击。HTTP/2以 Google的SPDY/2 为基础开发,实现异步连接多路复用、头部压缩、请求/响应管线化等目标。
这里写图片描述

二、HTTP/2特性

1.二进制传输

HTTP/2 采用二进制格式传输数据,而非 HTTP/1.x 的文本格式。二进制格式在协议的解析和优化扩展上带来更多的优势和可能

2.消息头压缩

HTTP/2 对消息头采用 HPACK 进行压缩传输,能够节省消息头占用的网络的流量。不像 HTTP/1.x 每次请求,都会携带大量冗余头信息,浪费了很多带宽资源。头压缩能够很好的解决该问题

3.多路复用

HTTP/1.x 有个问题叫队头堵塞,它是指一个连接(connection)一次只提交一个请求的效率比较高, 多了就会变慢,在应对并发的时候,往往客户端必须通过创建连接池实现,而HTTP/2 复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了”队头堵塞”

4.服务推送

当连接创建时,服务端也能够更快的把资源主动推送给客户端。例如服务端可以主动把 JS 和 CSS 文件推送给客户端,而不需要客户端解析 HTML 再发送这些请求

5.流量控制

HTTP/2上面每个流都拥有自己的公示的流量窗口,它可以限制另一端发送数据。对于每个流来说,两端都必须告诉对方自己还有更多的空间来接受新的数据,而在该窗口被扩大前,另一端只被允许发送这么多数据

三、HTTP/2连接过程

这里写图片描述
上图详细展示了客户端和服务端采用HTTP/2协议通信整个过程,包括创建连接、发送接受消息、结束。为了说明上述流程我们先来了解流(Stream)、消息(Message) 和帧(Frame)
- Stream 处于一个连接中的双向二进制数据流,可以包含一个或者多个 Message。
- Message 一个完整的请求或者响应,包含多个 Frame 序列。
- Frame HTTP/2 通讯中的最小传输单位,至少含有一个 Frame header,能够表示它属于哪一个 Stream。

1.首先客户端会发一个字符串(PRI * HTTP/2.0)到服务端,表示即将要通过HTTP/2来通信
2.接着客户端发送SETTINGS帧给服务端,服务端收到后也会返回SETTINGS帧
3.客户端会发送流控给服务端,同样服务端会返回。
4.最终客户端会发送SETTINGS帧确认ack=true给服务端,同样服务端也会返回ack=true,到此通道创建完成
5.客户端发送消息请求的时候,分HEADERS和DATA帧发送,并且帧里面带有streamId来辨别是哪个消息,同样服务端也会返回HEADERS和DATA帧,带有客户端请求过来的streamId
6.关闭连接发送GO_AWAY帧

四、HTTP/2基石frame

1.frame结构

Frame 是 HTTP/2 二进制格式的基础,基本可以把它理解为它 TCP 里面的数据包一样。HTTP/2 之所以能够有如此多的新特性,正是因为底层数据格式的改变,其格式如下。
这里写图片描述
帧包括以下字段(从左往右):
payloadLength(负载长度3byte)+type(frame类型1byte)+flags(标志位1byte)+streamId(消息id3byte)+framePayload(负载内容payloadLength/byte)

eg.一串二进制数据 00 00 00 04 01 00 00 00 00
我们可以分析出它的负载长度0,帧的类型是4代表SETTINGS帧,标志为1表示true,streamId为0,表示是创建连接时候的SETTINGS 帧内容ack=true

注意:关于帧长度,需要稍加关注: - 0 ~ 2^14(16384)为默认约定长度,所有端点都需要遵守 - 2^14 (16,384) ~ 2^24-1(16,777,215)此区间数值,需要接收方设置SETTINGS_MAX_FRAME_SIZE参数单独赋值 - 一端接收到的帧长度超过设定上限或帧太小,需要发送FRAME_SIZE_ERR错误 - 当帧长错误会影响到整个连接状态时,须以连接错误对待之;比如HEADERS,PUSH_PROMISE,CONTINUATION,SETTINGS,以及帧标识符不该为0的帧等,都需要如此处理 - 任一端都没有义务必须使用完一个帧的所有可用空间 - 大帧可能会导致延迟,针对时间敏感的帧,比如RST_STREAM, WINDOW_UPDATE, PRIORITY,需要快速发送出去,以免延迟导致性能等问题

2.SETTINGS

设置帧frame type=4,接收者向发送者通告己方设定,服务器端在连接成功后必须第一个发送的帧。

字段Identifier定义了如下参数: - SETTINGS_HEADER_TABLE_SIZE (0x1),通知接收者报头表的字节数最大值,报头块解码使用;初始值为4096个字节,默认可不用设置 - SETTINGS_ENABLE_PUSH (0x2),0:禁止服务器推送,1:允许推送;其它值非法,PROTOCOL_ERROR错误 - SETTINGS_MAX_CONCURRENT_STREAMS (0x3),发送者允许可打开流的最大值,建议值100,默认可不用设置;0值为禁止创建新流 - SETTINGS_INITIAL_WINDOW_SIZE (0x4),发送端流控窗口大小,默认值2^16-1 (65,535)个字节大小;最大值为2^31-1个字节大小,若溢出需要报FLOW_CONTROL_ERROR错误 - SETTINGS_MAX_FRAME_SIZE (0x5),单帧负载最大值,默认为2^14(16384)个字节,两端所发送帧都会收到此设定影响;值区间为2^14(16384)-2^24-1(16777215) - SETTINGS_MAX_HEADER_LIST_SIZE (0x6),发送端通告自己准备接收的报头集合最大值,即字节数。此值依赖于未压缩报头字段,包含字段名称、字段值以及每一个报头字段的32个字节的开销等;文档里面虽说默认值不受限制,因为受到报头集合大小不限制的影响,个人认为不要多于2 SETTINGS_MAX_FRAME_SIZE(即2^142=32768),否则包头太大,隐患多多

标志位: * ACK (0x1),表示接收者已经接收到SETTING帧,作为确认必须设置此标志位,此时负载为空,否则需要报FRAME_SIZE_ERROR错误

3.WINDOW_UPDATE

流量控制帧frame type=8,流量控制帧,作用于单个流以及整个连接,但只能影响两个端点之间传输的DATA数据帧

字段列表: - Window Size Increment,31个比特位无符号自然数,范围为1-2^31-1(2,147,483,647)个字节数,表明发送者可以发送的最大字节数,以及接收者可以接收到的最大字节数。

4.HEADERS

头帧frame type=1,报头主要载体,请求头或响应头,同时呢也用于打开一个流,在流处于打开”open”或者远程半关闭”half closed (remote)”状态都可以发送。

字段列表: - Pad Length:受制于PADDED标志控制是否显示,8个比特表示填充的字节数。 - E:一个比特表示流依赖是否专用,可选项,只在流优先级PRIORITY被设置时有效 - Stream Dependency:31个比特表示流依赖,只在流优先级PRIORITY被设置时有效 Weight:8个比特(一个字节)表示无符号的自然数流优先级,值范围自然是(1~256),或称之为权重。只在流优先级PRIORITY被设置时有效 - Header Block Fragment:报头块分片 - Padding:填充的字节,受制于PADDED标志控制是否显示,长度由Pad Length字段决定

所需标志位: END_STREAM (0x1): 报头块为最后一个,意味着流的结束。后续可紧接着CONTINUATION帧在当前的流中,需要把CONTINUATION帧作为HEADERS帧的一部分对待 END_HEADERS (0x4): 此报头帧不需分片,完整的一个帧。后续不再需要CONTINUATION帧帮忙凑齐。若没有此标志的HEADER帧,后续帧必须是以CONTINUATION帧传递在当前的流中,否则接收者需要响应PROTOCOL_ERROR类型的连接错误。 PADDED (0x8): 需要填充的标志 PRIORITY (0x20): 优先级标志位,控制独立标志位E,流依赖,和流权重。

5.DATA

数据帧 frame type=0

字段: Pad Length: 一个字节表示填充的字节长度。取决于PADDED标志是否被设置. Data: 这里是应用数据,真正大小需要减去其他字段(比如填充长度和填充内容)长度。 * Padding: 填充内容为若干个0x0字节,受PADDED标志控制是否显示。接收端处理时可忽略验证填充内容。若验证,可以对非0x0内容填充回应PROTOCOL_ERROR类型连接异常。

标志位: END_STREAM (0x1): 标志此帧为对应标志流最后一个帧,流进入了半关闭/关闭状态。 PADDED (0x8): 负载需要填充,Padding Length + Data + Padding组成。

6.PUSH_PROMISE

服务端推送消息帧 frame type=5

字段列表: - Promised Stream ID,31个比特表示无符号的自然数,为推送保留的流标识符,后续适用于发送推送数据 - Header Block Fragment,请求头部字段值,可看做是服务器端模拟客户端发起一次资源请求

标志位: END_HEADERS(0x4/00000010),此帧包含完整的报头块,不用后面跟随CONTINUATION帧了 PADDED(0x8/00000100),填充开关,决定了下面的Pad Length和Padding是否要填充,具体和HEADERS帧内容一致

7.GOAWAY

连接关闭帧 frame type=7,一端通知对端较为优雅的方式停止创建流。

五、其它

与HTTP/1比较:
这里写图片描述
目前支持的容器与框架:netty、grpc、tomcat9、nginx

展望未来:HTTP/2定稿不久,但是其发展速度惊人,因为有众多优越的特性,还有Google作为强有力的推手,相信未来互联网应用HTTP/2将会取代HTTP/1

下面是官方给的一个HTTP/1和HTTP/2例子
https://http2.akamai.com/demo

资料:
https://github.com/fex-team/http2-spec/blob/master/HTTP2%E4%B8%AD%E8%8B%B1%E5%AF%B9%E7%85%A7%E7%89%88%2806-29%29.md
http://www.cnblogs.com/ghj1976/p/4552583.html
http://www.blogjava.net/yongboy/archive/2015/03/20/423655.html

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Tomcat是一个开源的Java Servlet容器,它实现了Servlet规范并提供了一个运行Java Web应用程序的环境。Tomcat的最新版本是Tomcat-9.0.0.M22,它支持Servlet 4.0和JSP 2.3,并提供了许多新特性。要运行Tomcat,您需要安装1.8或更高版本的JDK。\[1\] Tomcat的组件包括EndPoint、Processor、ProtocolHandler和Adapter。EndPoint是Coyote通信端点,负责监听通信端口并处理传输层的Socket接收和发送。Processor是Coyote协议处理接口,负责实现HTTP协议,它接收来自EndPoint的Socket,读取字节流并解析成Tomcat的Request和Response对象,然后通过Adapter将其提交给容器处理。ProtocolHandler是Coyote协议接口,通过EndPoint和Processor实现对具体协议的处理能力。Tomcat提供了6个不同的实现类来支持不同的协议和I/O模型。Adapter是适配器模式的经典应用,它将Tomcat的Request对象转换为标准的ServletRequest,然后调用容器进行处理。\[2\] Tomcat的Servlet容器是Catalina,它负责管理和执行Servlet的生命周期。在启动阶段,可以通过设置Catalina的await属性为true来监听SHUTDOWN命令。当收到该命令时,Tomcat会在主线程中执行Catalina的stop()方法来关闭服务器。默认情况下,SHUTDOWN命令监听的端口是8005。\[3\] 如果您想深入学习Tomcat,可以阅读Tomcat的官方文档和源代码,这将帮助您更好地理解Tomcat的内部工作原理和使用方法。您还可以参考一些Tomcat的教程和书籍,以获得更详细的学习资料和实践经验。 #### 引用[.reference_title] - *1* *3* [深入学习Tomcat 架构及启动过程](https://blog.csdn.net/J080624/article/details/86526494)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Tomcat深入学习与理解(一)Tomcat系统架构与原理分析](https://blog.csdn.net/qq_37551917/article/details/119681753)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值