3.3 多路复用
1.1版本中存在队首阻塞问题,因此如果客户端要发起多个并行请求来提升性能,必须使用多个 TCP 连接,这样就要承受更大延时和建链拆链成本,不能有效利用TCP链接。
由于2.0版本中使用新的二进制分帧协议突破了1.0的诸多限制,从根本上实现了真正的请求和响应多路复用。
客户端和服务器将交互数据分解为相互独立的帧,互不影响地交错传输,最后再在对端根据帧头中的流标识符把它们重新组装起来,从而实现了TCP链接的多路复用。
如图展示了2.0版本的基于帧的消息通信过程(图片来自参考4):
3.4 首部压缩
A.Header 冗余传输
我们都知道 http 请求都有 header 部分,每个包都有并且相对于一条链接而言大部分的包的 header 部分都是相同的,这样的话每次传输相同的部分确实非常浪费。
现代网络中每个网页平均包含100多个http请求,每个请求头平均有300-500字节,总数据量达到几十KB以上,这样可能造成数据延时,尤其复杂的WiFi环境或者蜂窝网络,这样只能看到手机在转圈,但是这些请求头之间通常几乎没有变化,在本已经拥挤的链路中多次传输相同的数据部分确实不是高效做法。
基于 TCP 设计的拥塞控制具有线增积减 AIMD 特性,如果发生丢包那么传输速率将大幅度下降,这样在拥挤的网络环境中大的包头意味着只能加剧拥塞控制造成的低速率传输。
B.Http 压缩和犯罪攻击
在2.0版本的 HPACK 算法之前,http 压缩使用 gzip 去压缩,后来提出的 SPDY 算法对 Headers 进行特殊设计,但是它依旧使用的是 DEFLATE 算法。
在后面的一些实际应用中发现 DEFLATE 和 SPDY 都有被攻击的危险,因为DEFLATE算法使用后向字符串匹配和动态 Huffman 编码,攻击者可以控制部分请求头部通过修改请求部分然后看压缩之后大小改变多少,如果变小了攻击者就知道注入的文本和请求中的某些内容有重复。
这个过程有点像俄罗斯方块的消除过程,这样经过一段时间的尝试数据内容就可能被全部搞清楚,由于这种风险的存在才研发出更安全的压缩算法。
C.HPACK 算法
2.0版本中HPACK算法在C/S中使用首部表来存储之前发送的键值对,对于相同的数据通信期间几乎不会改变的通用键值对只需发送一次即可。
极端情况如果请求头每次没有变化,那么传输中则不包含首部,也就是首部开销就是零字节。如果首部键值对发生变化了,也只需要发送变化的数据,并且将新增或修改的首部帧会被追加到首部表,首部表在链接存活期始终存在, 并且由客户端和服务器共同更新和维护。
简单说就是客户端和服务端共同维护了一个 key-value 的结构,发生变化时则更新传输,否则就不传输,这样相当于首次全量传输之后增量更新传输即可,这个思想在日常开发中也非常普遍,不用想的太复杂。
如图展示了首部表的更新过程(图片来自参考4):
hpack算法的相关文档:
https://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12
3.5 服务端推送
服务端推送是2.0版本新增的一个强大功能,和一般的一问一答式的C/S交互不同,推送式交互中服务器可以对客户端的一个请求发送多个响应,除了对最初请求的响应外还向客户端推送额外资源,无需客户端明确地请求也可以推送。
举个栗子:
想象一下你去餐厅吃饭,服务好的快餐厅在你点好一份牛肉面之后,还会给你送上餐巾纸、筷子、勺子甚至调料等,这样主动式的服务,节约了客人的时间并且提高了用餐体验。
在实际的 C/S 交互中这种主动推送额外资源的方法很有效,因为几乎每个网络应用都会包含多种资源,客户端需要全部逐个获取它们,此时如果让服务器提前推送这些资源,从而可以有效减少额外的延迟时间,因为服务器可以知道客户端下一步要请求什么资源。
如图为服务端推送的简单过程(图片来自参考4):
4. 总结
本文通过介绍 Http 协议的历史演进、各个版本的主要特征和优缺点、重点介绍了Http 2.0协议的一些特性,包括:SPDY协议、二进制分帧协议、多路复用、首部压缩、服务端推送等重要功能,篇幅有限不能展开太多。
虽然 http 2.0版本协议有很多非常优秀的功能并且在2015年正式发布,现在国内外一些大厂基本都有使用 http 2.0承担部分请求,但是目前仍然未广泛普及。
目前http3.0版本在2018年也推出来了,至于 http 2.0和 http 3.0的推广和普及是需要时间的,但是坚信我们的网络可以更安全、更快捷、更节约。
本次的旅程就此结束啦,期待下一次的航行!
5.巨人的肩膀
- https://juejin.im/post/5d9abde7e51d4578110dc77f
- https://lixiaoyu.cc/2018/09/04/computer-network-12-http-version-differences/
- https://www.ibm.com/developerworks/cn/web/wa-http2-under-the-hood/index.html
- https://developers.google.com/web/fundamentals/performance/http2?hl=zh-cn
- https://hpbn.co/primer-on-web-performance/#latency-as-a-performance-bottleneck
- https://httpwg.org/specs/rfc7540.html
- https://juejin.im/post/5d033d3df265da1baa1e700e
- https://juejin.im/post/5da16e9ef265da5b76373d0e